< Summary

Information
Class: TeleFlow.Framework.Application.TeleFlowApplication
Assembly: TeleFlow.Framework.Core
File(s): /_/src/TeleFlow.Framework.Core/Application/TeleFlowApplication.cs
Line coverage
93%
Covered lines: 41
Uncovered lines: 3
Coverable lines: 44
Total lines: 125
Line coverage: 93.1%
Branch coverage
62%
Covered branches: 15
Total branches: 24
Branch coverage: 62.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%88100%
CreateBuilder(...)100%11100%
RunAsync()100%22100%
ProcessUpdateAsync(...)100%11100%
Dispose()66.66%6687.5%
DisposeAsync()62.5%8881.81%

File(s)

/_/src/TeleFlow.Framework.Core/Application/TeleFlowApplication.cs

#LineLine coverage
 1using System.Diagnostics.CodeAnalysis;
 2using System.Runtime.ExceptionServices;
 3using TeleFlow.Framework.Updates;
 4
 5namespace TeleFlow.Framework.Application;
 6
 7public sealed class TeleFlowApplication : ITeleFlowApplication
 8{
 9    private readonly IServiceProvider _services;
 10    private readonly IUpdateSource _updateSource;
 11    private readonly IUpdateProcessor _updateProcessor;
 12    private readonly TeleFlowApplicationLifecycleRunner _lifecycle;
 13    private readonly bool _ownsServices;
 14    private bool _disposed;
 15
 16    internal TeleFlowApplication(
 17        IServiceProvider services,
 18        IUpdateSource updateSource,
 19        IUpdateProcessor updateProcessor,
 20        TeleFlowApplicationLifecycleRunner lifecycle,
 21        bool ownsServices)
 22    {
 4823        _services = services ?? throw new ArgumentNullException(nameof(services));
 4824        _updateSource = updateSource ?? throw new ArgumentNullException(nameof(updateSource));
 4825        _updateProcessor = updateProcessor ?? throw new ArgumentNullException(nameof(updateProcessor));
 4826        _lifecycle = lifecycle ?? throw new ArgumentNullException(nameof(lifecycle));
 4827        _ownsServices = ownsServices;
 4828    }
 29
 30    public static ITeleFlowApplicationBuilder CreateBuilder(string[]? args = null)
 31    {
 5532        return new TeleFlowApplicationBuilder(args);
 33    }
 34
 35    [SuppressMessage(
 36        "Design",
 37        "CA1031:Do not catch general exception types",
 38        Justification = "The application must run shutdown tasks for any update-source failure while preserving and reth
 39    public async Task RunAsync(CancellationToken cancellationToken = default)
 40    {
 4541        ObjectDisposedException.ThrowIf(_disposed, this);
 42
 4443        await _lifecycle.RunStartupAsync(cancellationToken).ConfigureAwait(false);
 44
 4245        ExceptionDispatchInfo? updateSourceException = null;
 46
 47        try
 48        {
 4249            await _updateSource.StartAsync(ProcessUpdateAsync, cancellationToken).ConfigureAwait(false);
 3550        }
 751        catch (Exception exception)
 52        {
 753            updateSourceException = ExceptionDispatchInfo.Capture(exception);
 754        }
 55
 56        try
 57        {
 4258            await _lifecycle.RunShutdownAsync(cancellationToken).ConfigureAwait(false);
 4159        }
 160        catch (Exception shutdownException) when (updateSourceException is not null)
 61        {
 162            throw new AggregateException(updateSourceException.SourceException, shutdownException);
 63        }
 64
 4165        if (updateSourceException is not null)
 66        {
 667            updateSourceException.Throw();
 68        }
 3569    }
 70
 71    internal Task ProcessUpdateAsync(IUpdatePayload payload, CancellationToken cancellationToken)
 72    {
 5073        ObjectDisposedException.ThrowIf(_disposed, this);
 5074        ArgumentNullException.ThrowIfNull(payload);
 75
 5076        return _updateProcessor.ProcessAsync(payload, cancellationToken);
 77    }
 78
 79    public void Dispose()
 80    {
 381        if (_disposed)
 82        {
 183            return;
 84        }
 85
 286        _disposed = true;
 87
 288        if (!_ownsServices)
 89        {
 090            return;
 91        }
 92
 293        if (_services is IDisposable disposable)
 94        {
 295            disposable.Dispose();
 96        }
 297    }
 98
 99    public async ValueTask DisposeAsync()
 100    {
 12101        if (_disposed)
 102        {
 1103            return;
 104        }
 105
 11106        _disposed = true;
 107
 11108        if (!_ownsServices)
 109        {
 3110            return;
 111        }
 112
 8113        if (_services is IAsyncDisposable asyncDisposable)
 114        {
 8115            await asyncDisposable.DisposeAsync().ConfigureAwait(false);
 8116            return;
 117        }
 118
 0119        if (_services is IDisposable disposable)
 120        {
 0121            disposable.Dispose();
 122        }
 12123    }
 124
 125}