The IServiceProvider is responsible for resolving instances of types at runtime, as required by the application. These instances can be injected into other services resolved from the same dependency injection container. The ServiceProvider ensures that resolved services live for the expected lifetime.
Resolve dependencies using IServiceProvider Once the container has been created, the IServiceCollection instance is composed into an IServiceProvider instance. You can use this instance to resolve services. You can inject an instance of type IServiceProvider into any method of a class.
The ASP.NET Core DI container has a root IServiceProvider which is used to resolve singleton services. For scoped services, the container must first create a new scope, and each scope will have it's own IServiceProvider .
ASP.NET Core contains a built-in dependency injection mechanism. In the Startup. cs file, there is a method called ConfigureServices which registers all application services in the IServiceCollection parameter. The collection is managed by the Microsoft.
As goaty mentioned it's enough to create new ServiceCollection
. Here's example class which can be used to access DI container in .NET Core:
public static class ServiceProviderFactory
{
public static IServiceProvider ServiceProvider { get; }
static ServiceProviderFactory()
{
HostingEnvironment env = new HostingEnvironment();
env.ContentRootPath = Directory.GetCurrentDirectory();
env.EnvironmentName = "Development";
Startup startup = new Startup(env);
ServiceCollection sc = new ServiceCollection();
startup.ConfigureServices(sc);
ServiceProvider = sc.BuildServiceProvider();
}
}
Startup
class is taken from tested project so the service registrations don't need to be repeated.
Then in test class simply use:
var foo = ServiceProviderFactory.ServiceProvider.GetServices(typeof(IFoo));
This is the default implementation of IServiceCollection
from Microsoft:
https://github.com/aspnet/DependencyInjection/blob/master/src/DI/ServiceCollection.cs
Looking at the code then you should be able to get an IServiceCollection
simply by calling:
var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
Hope that helps :)
To get access to existing DI of ASP.NET Core application e.g. in some controller, you should just resolve it in a constructor. Example with some manager and workers:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IFooManager, FooManager>();
services.AddTransient<IFooWorker, FooWorker>();
}
Manually resolve workers for manager:
public class FooManager: IFooManager
{
private readonly IServiceProvider _di;
public FooManager(IServiceProvider serviceProvider)
{
_di = serviceProvider;
}
public void Start()
{
var w1 = _di.GetRequiredService<IFooWorker>(); // new instance of FooWorker
var w2 = _di.GetRequiredService<IFooWorker>(); // new instance of FooWorker
}
}
Here is an updated approach:
var host = Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder =>
{
builder.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
env.ContentRootPath = Directory.GetCurrentDirectory();
env.EnvironmentName = "Development";
});
builder.UseStartup<Startup>();
}).Build();
Example usage:
host.Services.GetService<IFoo>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With