如何在.NET Core中获取IServiceProvider的实例?

时间:2017-02-14 09:08:40

标签: dependency-injection .net-core service-provider

IServiceProvider是一个单一方法的接口:

object GetService(Type serviceType);

它用于创建在.NET Core本机DI容器中注册的类型的实例。

IServiceProvider本身的实例可以通过调用BuildServiceProvider的{​​{1}}方法获得。 IServiceCollectionIServiceCollection类中ConfigureServices方法的参数。它似乎被框架中的Startup实例神奇地调用了。

我想创建IServiceCollection的实例而根本没有IServiceProvider方法。我需要它来解决集成测试程序集中的依赖项。在这种情况下是否可以获得它?

7 个答案:

答案 0 :(得分:36)

正如 goaty 所提到的,它足以创建新的 #***************************************************************** # Network connector configuration #***************************************************************** # With default configuration Neo4j only accepts local connections. # To accept non-local connections, uncomment this line: dbms.connectors.default_listen_address=0.0.0.0 # You can also choose a specific network interface, and configure a non-default # port for each connector, by setting their individual listen_address. # The address at which this server can be reached by its clients. This may be the server's IP address or DNS name, or # it may be the address of a reverse proxy which sits in front of the server. This setting may be overridden for # individual connectors below. #dbms.connectors.default_advertised_address=localhost # You can also choose a specific advertised hostname or IP address, and # configure an advertised port for each connector, by setting their # individual advertised_address. # Bolt connector dbms.connector.bolt.enabled=true #dbms.connector.bolt.tls_level=OPTIONAL #dbms.connector.bolt.listen_address=:7687 # HTTP Connector. There must be exactly one HTTP connector. dbms.connector.http.enabled=true #dbms.connector.http.listen_address=:7474 。这是一个示例类,可用于访问.NET Core中的DI容器:

ServiceCollection

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

答案 1 :(得分:15)

这是Microsoft的IServiceCollection的默认实现: https://github.com/aspnet/DependencyInjection/blob/master/src/DI/ServiceCollection.cs

查看代码,您只需致电:

即可获得var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
{{1}}

希望有所帮助:)

答案 2 :(得分:3)

这是一种更新的方法:

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();

用法示例:

host.Services.GetService<IFoo>();

答案 3 :(得分:3)

要访问ASP.NET Core应用程序的现有DI,例如在某些控制器中,您应该在Startup.cs的ConfigureServices方法中注册它:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
   services.AddMvc();
   services.AddSingleton(services);   //  <- here

   // ... other DI registrations
   services.AddSingleton<IFooManager, FooManager>();
   services.AddTransient<IFooWorker, FooWorker>();
}

之后,您可以像下面这样在DI的任何已解析对象中使用它:

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
    }
}

答案 4 :(得分:1)

您可以在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();
}

答案 5 :(得分:0)

首先,您需要安装Microsoft.Extensions.DependencyInjection NuGet软件包。 (docsAPIAPI

然后您创建一个新的ServiceCollection并使用BuildServiceProvider方法将其链接。在此期间,您还可以注册任何服务提供商。

var serviceProvider = new ServiceCollection()
    .AddSingleton<IFooService, FooService>()
    .BuildServiceProvider();

答案 6 :(得分:-2)

public static class ServiceTool
{
    public static IServiceProvider ServiceProvider { get; private set; }
    public static IServiceCollection Create(IServiceCollection services)
    {
        ServiceProvider = services.BuildServiceProvider();
        return services;
    }
}
//set operations
services.AddSingleton(typeof(IRepository<>), typeof(EfRepository<,>));
ServiceTool.Create(services);  

//get operations
var rep = ServiceTool.ServiceProvider.GetService<IRepository<Account>>();