< Summary

Information
Class: TeleFlow.Telegram.TelegramClientServiceCollectionExtensions
Assembly: TeleFlow.Telegram.Client
File(s): /_/src/TeleFlow.Telegram.Client/TelegramClientServiceCollectionExtensions.cs
Line coverage
85%
Covered lines: 69
Uncovered lines: 12
Coverable lines: 81
Total lines: 185
Line coverage: 85.1%
Branch coverage
66%
Covered branches: 4
Total branches: 6
Branch coverage: 66.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/_/src/TeleFlow.Telegram.Client/TelegramClientServiceCollectionExtensions.cs

#LineLine coverage
 1using System.Text.Json;
 2using Microsoft.Extensions.DependencyInjection;
 3using Microsoft.Extensions.DependencyInjection.Extensions;
 4using Microsoft.Extensions.Logging;
 5using Microsoft.Extensions.Logging.Abstractions;
 6using TeleFlow.Telegram.Internal;
 7using TeleFlow.Telegram.Internal.Options;
 8
 9namespace TeleFlow.Telegram;
 10
 11public static class TelegramClientServiceCollectionExtensions
 12{
 13    public static IServiceCollection AddTelegramClient(
 14        this IServiceCollection services,
 15        Action<TelegramClientOptions> configure)
 16    {
 49017        ArgumentNullException.ThrowIfNull(services);
 49018        ArgumentNullException.ThrowIfNull(configure);
 19
 49020        EnsureNotRegistered<TelegramClientOptions>(services, nameof(AddTelegramClient));
 21
 49022        var options = new TelegramClientOptions();
 49023        configure(options);
 49024        TelegramClientOptionsValidator.Validate(options);
 25
 48026        services.AddSingleton(options);
 48027        AddTelegramClientDefaults(services);
 28
 48029        return services;
 30    }
 31
 32    public static IServiceCollection AddDeepLinkPayloadSerializer<TSerializer>(
 33        this IServiceCollection services)
 34        where TSerializer : class, IDeepLinkPayloadSerializer
 35    {
 136        ArgumentNullException.ThrowIfNull(services);
 37
 138        services.RemoveAll<IDeepLinkPayloadSerializer>();
 139        services.AddSingleton<IDeepLinkPayloadSerializer, TSerializer>();
 140        return services;
 41    }
 42
 43    public static IServiceCollection AddTelegramJsonOptions(
 44        this IServiceCollection services,
 45        JsonSerializerOptions options)
 46    {
 047        ArgumentNullException.ThrowIfNull(services);
 048        ArgumentNullException.ThrowIfNull(options);
 49
 050        services.RemoveAll<TelegramJsonOptions>();
 051        services.AddSingleton(new TelegramJsonOptions(options));
 052        return services;
 53    }
 54
 55    public static IServiceCollection AddTelegramJsonOptions(
 56        this IServiceCollection services,
 57        Action<JsonSerializerOptions> configure)
 58    {
 159        ArgumentNullException.ThrowIfNull(services);
 160        ArgumentNullException.ThrowIfNull(configure);
 61
 162        var options = TelegramJsonOptions.CreateDefault().SerializerOptions;
 163        configure(options);
 64
 165        services.RemoveAll<TelegramJsonOptions>();
 166        services.AddSingleton(new TelegramJsonOptions(options));
 167        return services;
 68    }
 69
 70    public static IServiceCollection AddTelegramHttpTransport(
 71        this IServiceCollection services,
 72        HttpClient httpClient)
 73    {
 074        ArgumentNullException.ThrowIfNull(services);
 075        ArgumentNullException.ThrowIfNull(httpClient);
 76
 077        services.RemoveAll<ITelegramTransport>();
 078        services.AddSingleton<ITelegramTransport>(_ => new HttpClientTelegramTransport(httpClient));
 079        return services;
 80    }
 81
 82    public static IServiceCollection AddTelegramHttpTransport(
 83        this IServiceCollection services,
 84        Func<IServiceProvider, HttpClient> httpClientFactory)
 85    {
 6986        ArgumentNullException.ThrowIfNull(services);
 6987        ArgumentNullException.ThrowIfNull(httpClientFactory);
 88
 6989        services.RemoveAll<ITelegramTransport>();
 6990        services.AddSingleton<ITelegramTransport>(provider =>
 6991        {
 6992            var httpClient = httpClientFactory(provider);
 6993            ArgumentNullException.ThrowIfNull(httpClient);
 6994            return HttpClientTelegramTransport.CreateOwned(httpClient);
 6995        });
 6996        return services;
 97    }
 98
 99    public static IServiceCollection AddTelegramTransport<TTransport>(
 100        this IServiceCollection services)
 101        where TTransport : class, ITelegramTransport
 102    {
 1103        ArgumentNullException.ThrowIfNull(services);
 104
 1105        services.RemoveAll<ITelegramTransport>();
 1106        services.AddSingleton<ITelegramTransport, TTransport>();
 1107        return services;
 108    }
 109
 110    public static IServiceCollection AddTelegramHttpMessageHandler<THandler>(
 111        this IServiceCollection services)
 112        where THandler : HttpMessageHandler
 113    {
 1114        ArgumentNullException.ThrowIfNull(services);
 115
 1116        services.RemoveAll<ITelegramTransport>();
 1117        services.AddSingleton<ITelegramTransport>(provider =>
 2118            HttpClientTelegramTransport.CreateOwned(new HttpClient(
 2119                provider.GetRequiredService<THandler>(),
 2120                disposeHandler: false)));
 1121        return services;
 122    }
 123
 124    public static IServiceCollection AddTelegramClient<TClient>(
 125        this IServiceCollection services)
 126        where TClient : class, ITelegramClient
 127    {
 1128        ArgumentNullException.ThrowIfNull(services);
 129
 1130        services.RemoveAll<ITelegramClient>();
 1131        services.AddSingleton<ITelegramClient, TClient>();
 1132        return services;
 133    }
 134
 135    public static IServiceCollection AddTelegramRequestExecutor<TExecutor>(
 136        this IServiceCollection services)
 137        where TExecutor : class, ITelegramRequestExecutor
 138    {
 1139        ArgumentNullException.ThrowIfNull(services);
 140
 1141        services.RemoveAll<ITelegramRequestExecutor>();
 1142        services.AddSingleton<ITelegramRequestExecutor, TExecutor>();
 1143        return services;
 144    }
 145
 146    /// <summary>
 147    /// Replaces the default fail-closed policy used when an individual Telegram update cannot be decoded.
 148    /// </summary>
 149    public static IServiceCollection AddTelegramUpdateDecodeFailurePolicy<TPolicy>(
 150        this IServiceCollection services)
 151        where TPolicy : class, ITelegramUpdateDecodeFailurePolicy
 152    {
 3153        ArgumentNullException.ThrowIfNull(services);
 154
 3155        services.RemoveAll<ITelegramUpdateDecodeFailurePolicy>();
 3156        services.AddSingleton<ITelegramUpdateDecodeFailurePolicy, TPolicy>();
 3157        return services;
 158    }
 159
 160    private static void AddTelegramClientDefaults(IServiceCollection services)
 161    {
 480162        services.TryAddSingleton(TelegramJsonOptions.CreateDefault());
 480163        services.TryAddSingleton<IDeepLinkPayloadSerializer, Base64UrlJsonDeepLinkPayloadSerializer>();
 480164        services.TryAddSingleton<TelegramDeepLinks>(static provider =>
 787165            new TelegramDeepLinks(
 787166                provider.GetRequiredService<TelegramClientOptions>().BotUsername,
 787167                provider.GetRequiredService<IDeepLinkPayloadSerializer>()));
 697168        services.TryAddSingleton<ITelegramTransport>(static _ => HttpClientTelegramTransport.CreateOwned(new HttpClient(
 480169        services.TryAddSingleton(TimeProvider.System);
 480170        services.TryAddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
 480171        services.TryAddSingleton<ITelegramClient, TelegramClient>();
 480172        services.TryAddSingleton<ITelegramRequestExecutor, TelegramRequestExecutor>();
 480173        services.TryAddSingleton<ITelegramUpdateBatchReceiver, TelegramUpdateBatchReceiver>();
 480174        services.TryAddSingleton<ITelegramUpdateDecodeFailurePolicy>(StopTelegramUpdateDecodeFailurePolicy.Instance);
 480175    }
 176
 177    private static void EnsureNotRegistered<TService>(IServiceCollection services, string apiName)
 178    {
 1759179        if (services.Any(descriptor => descriptor.ServiceType == typeof(TService)))
 180        {
 0181            throw new InvalidOperationException(
 0182                $"{apiName} cannot be called more than once for service '{typeof(TService).Name}'.");
 183        }
 490184    }
 185}