Search code examples
c#.netdependency-injectionintegration-testing

Does anyone know why the C#/.NET DI Container thinks my dependency is Scoped when declared as a singleton?


I'm currently implementing a new feature, but when I try to run the integration tests for the project, the DI container throws an exception. It thinks the dependency I'm calling from my BackgroundService is declared as a Scoped service, but in reality it's added as a Singleton.

I have declared my service like this:

services.AddSingleton<IX, X>();

This is the error I'm getting:

System.AggregateException
Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: X.XWorker': Cannot consume scoped service 'X.IX' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection`1 serviceDescriptors, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.Hosting.HostApplicationBuilder.<>c__DisplayClass12_0.<.ctor>b__0()
   at Microsoft.Extensions.Hosting.HostApplicationBuilder.Build()
   at X.IntegrationTests.WorkerFixture.InitializeAsync() in C:\Users\X\tests\X.Worker.IntegrationTests\WorkerFixture.cs:line 97
   at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in /_/src/xunit.core/Sdk/ExceptionAggregator.cs:line 90

I've tried re-declaring the service in a different place and re-declaring the service within the WorkerFixture itself, but no success yet.


Solution

  • @Lei Chi's comment made me look once more, and I've found the issue. Apparently, in the setup of the integration tests, there is a section that removes certain classes from DI and re-adds a mocked version of them... as Scoped (which obviously does not make any sense).

    This is the section I am referring to:

    foreach (var (interfaceType, serviceMock) in MockServices.GetMocks())
    {
        builder.Services.Remove(builder.Services.SingleOrDefault(d => d.ServiceType == interfaceType)!);
        builder.Services.AddScoped(interfaceType, _ => serviceMock);
    }
    

    Changing builder.Services.AddScoped(..); to builder.Services.AddSingleton(..); did the trick!