Search code examples
c#asp.net-core.net-6.0service-provider

Injecting the IServiceProvider for the current request scope


In an ASP.NET Core 6 app, adding IServiceProvider to the service collection in this way allows injection of a scoped provider:

services.AddScoped(sp => sp);

But is it the scoped provider for the current request? In other words, is it guaranteed to provide the same instances of scoped dependencies that may have been injected elsewhere in the request?

XY: Method boundary callbacks are added to the service collection at startup. I'm injecting a service provider rather than the callbacks for two reasons: to break potential circular dependencies; and to avoid instantiating callbacks for all methods when only one method is being called.


Solution

  • First of all you don't need to register service provider explicitly, it should be available without any extra registrations.

    Second of all resolving IServiceProvider from the scope, at least ATM (.NET 6) not only returns the same scoped provider, but the same instance:

    var services = new ServiceCollection();
    services.AddScoped<MyScopedDep>();
    var serviceProvider = services.BuildServiceProvider();
    using var serviceScope = serviceProvider.CreateScope();
    var providerResolvedFromScope = serviceScope.ServiceProvider.GetRequiredService<IServiceProvider>();
    Console.WriteLine(object.ReferenceEquals(serviceScope.ServiceProvider, providerResolvedFromScope)); // prints "True"
    Console.WriteLine(object.ReferenceEquals(serviceScope.ServiceProvider.GetRequiredService<MyScopedDep>(), providerResolvedFromScope.GetRequiredService<MyScopedDep>())); // prints "True"
    

    And from the docs:

    For example, if you resolve services from a scope, and any of those services take an IServiceProvider, it'll be a scoped instance.