< Summary - AsyncResponse (Release / net8.0+net10.0 / unit+integration)

Information
Class: Microsoft.Extensions.DependencyInjection.MongoDbAsyncResponseChannelServiceCollectionExtensions
Assembly: AsyncResponse.Channels.MongoDB
File(s): /home/runner/work/AsyncResponse/AsyncResponse/src/Channels/AsyncResponse.Channels.MongoDB/ServiceCollectionExtensions.cs
Line coverage
100%
Covered lines: 42
Uncovered lines: 0
Coverable lines: 42
Total lines: 77
Line coverage: 100%
Branch coverage
100%
Covered branches: 30
Total branches: 30
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
WithMongoDbChannel(...)100%2222100%

File(s)

/home/runner/work/AsyncResponse/AsyncResponse/src/Channels/AsyncResponse.Channels.MongoDB/ServiceCollectionExtensions.cs

#LineLine coverage
 1using AsyncResponse;
 2using AsyncResponse.Channels.MongoDB;
 3using Microsoft.Extensions.DependencyInjection.Extensions;
 4using Microsoft.Extensions.Options;
 5using MongoDB.Driver;
 6
 7namespace Microsoft.Extensions.DependencyInjection;
 8
 9/// <summary>DI registration for the MongoDB-backed AsyncResponse channel package.</summary>
 10public static class MongoDbAsyncResponseChannelServiceCollectionExtensions
 11{
 12    /// <summary>
 13    /// Registers MongoDB change streams as the response channel — behind
 14    /// <see cref="IAsyncResponsePublisher"/>, <see cref="IAsyncResponseSubscriber"/>, and
 15    /// <see cref="IRecoverableAsyncResponseSubscriber"/> — together with the durable TTL-indexed
 16    /// MongoDB recovery-state store. Hosts may register an <see cref="IMongoDatabase"/> (or an
 17    /// <see cref="IMongoClient"/> plus <see cref="MongoDbAsyncResponseChannelOptions.DatabaseName"/>)
 18    /// singleton, or set <see cref="MongoDbAsyncResponseChannelOptions.ConnectionString"/> here.
 19    /// Change streams require the server to run as a replica set (single-node is sufficient).
 20    /// </summary>
 21    public static AsyncResponseRegistrationBuilder WithMongoDbChannel(
 22        this AsyncResponseRegistrationBuilder builder,
 23        Action<MongoDbAsyncResponseChannelOptions>? configure = null)
 24    {
 325        var services = builder.Services;
 326        services.AddOptions();
 327        if (configure is not null)
 328            services.Configure(configure);
 29
 30        // The store reuses a host-registered IMongoDatabase / IMongoClient when present; otherwise it
 31        // creates and owns a client from the options. Nothing is registered as a bare
 32        // IMongoClient/IMongoDatabase service, so unrelated resolutions of those types are never
 33        // answered — or broken — by this package.
 334        services.TryAddSingleton(provider =>
 335        {
 336            var options = provider.GetRequiredService<IOptions<MongoDbAsyncResponseChannelOptions>>();
 337
 338            var database = provider.GetService<IMongoDatabase>();
 339            if (database is not null)
 340                return new MongoDbChannelStore(database, options);
 341
 342            if (string.IsNullOrWhiteSpace(options.Value.DatabaseName))
 343                throw new InvalidOperationException($"{nameof(MongoDbAsyncResponseChannelOptions)}.{nameof(MongoDbAsyncR
 344
 345            var sharedClient = provider.GetService<IMongoClient>();
 346            if (sharedClient is not null)
 347                return new MongoDbChannelStore(sharedClient.GetDatabase(options.Value.DatabaseName), options);
 348
 349            if (string.IsNullOrWhiteSpace(options.Value.ConnectionString))
 250                throw new InvalidOperationException($"{nameof(MongoDbAsyncResponseChannelOptions)}.{nameof(MongoDbAsyncR
 351
 252            var ownedClient = new MongoClient(options.Value.ConnectionString);
 353            return new MongoDbChannelStore(ownedClient.GetDatabase(options.Value.DatabaseName), options, ownedClient);
 354        });
 55
 356        services.TryAddSingleton<MongoDbRecoveryStateStore>();
 357        services.Replace(ServiceDescriptor.Singleton<IRecoveryStateStore>(provider => provider.GetRequiredService<MongoD
 358        services.Replace(ServiceDescriptor.Singleton<IRecoveryStateScanner>(provider => provider.GetRequiredService<Mong
 59
 360        services.TryAddSingleton<MongoDbAsyncResponseChannel>();
 361        services.Replace(ServiceDescriptor.Singleton<IAsyncResponsePublisher>(provider => provider.GetRequiredService<Mo
 362        services.Replace(ServiceDescriptor.Singleton<IRawAsyncResponsePublisher>(provider => provider.GetRequiredService
 363        services.Replace(ServiceDescriptor.Singleton<IAsyncResponseSubscriber>(provider => provider.GetRequiredService<M
 364        services.Replace(ServiceDescriptor.Singleton<IRecoverableAsyncResponseSubscriber>(provider => provider.GetRequir
 365        services.Replace(ServiceDescriptor.Singleton<IActiveSubscriberProbe>(provider => provider.GetRequiredService<Mon
 66
 367        services.Replace(ServiceDescriptor.Singleton<IRecoverableAsyncResponseBuilder>(provider => new RecoverableAsyncR
 368            provider.GetRequiredService<IRecoverableAsyncResponseSubscriber>(),
 369            provider.GetService<IWorkerTransport>(),
 370            provider.GetService<IAsyncResponseReplyTargetProvider>(),
 371            provider.GetRequiredService<AsyncResponseContextPropagation>())));
 372        services.Replace(ServiceDescriptor.Singleton<IAsyncResponseBuilder>(provider => provider.GetRequiredService<IRec
 73
 374        services.AddSingleton(new AsyncResponseChannelMarker(MongoDbAsyncResponseChannelOptions.ChannelName));
 375        return builder;
 76    }
 77}