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.
CodePudding user response:
First of all you don't need to register service provider, it is 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.