IServiceProvider is an interface with single method:
object GetService(Type serviceType);
It\'s used to create instances of ty
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>();
First you need to install the Microsoft.Extensions.DependencyInjection NuGet package. (docs, API, API)
Then you create a new ServiceCollection and method chain it with the BuildServiceProvider method. In between that you can also register any service providers.
var serviceProvider = new ServiceCollection()
.AddSingleton<IFooService, FooService>()
.BuildServiceProvider();
You can find it in Program.cs
public static IServiceProvider ServiceProvider { get; private set; }
public static void Main(string[] args)
{
IHost build = CreateHostBuilder(args).Build();
ServiceProvider = build.Services;
build.Run();
}
To get access to existing DI of ASP.NET Core application e.g. in some controller, you should register it in ConfigureServices method of Startup.cs:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton(services); // <- here
// ... other DI registrations
services.AddSingleton<IFooManager, FooManager>();
services.AddTransient<IFooWorker, FooWorker>();
}
After that, you can use it in any resolved objects from DI like this:
public class FooManager: IFooManager
{
private readonly ServiceProvider _di;
public FooManager(IServiceCollection serviceCollection)
{
_di = serviceCollection.BuildServiceProvider();
}
public void Start()
{
var w1 = _di.GetRequiredService<IFooWorker>(); // new instance of FooWorker
var w2 = _di.GetRequiredService<IFooWorker>(); // new instance of FooWorker
}
}
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 :)