How to get an instance of IServiceProvider in .NET

2019-02-04 04:29发布

IServiceProvider is an interface with single method:

object GetService(Type serviceType);

It's used to create instances of types registered in .NET Core native DI container.

An instance of IServiceProvider itself can be obtained by calling a BuildServiceProvider method of an IServiceCollection. IServiceCollection is a parameter of ConfigureServices method in a Startup class. It seems to be magically called with an instance of IServiceCollection by the framework.

I want to create an instance of IServiceProvider without having Setup method at all. I need it to resolve dependencies in an integration test assembly. Is it possible to get it at all in this scenario?

2条回答
可以哭但决不认输i
2楼-- · 2019-02-04 04:41

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));
查看更多
该账号已被封号
3楼-- · 2019-02-04 04:59

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 :)

查看更多
登录 后发表回答