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

How to get an instance of IServiceProvider in .NET Core?

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

object GetService(Type serviceType);

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

IServiceProvider本身的实例可以通过调用IServiceCollectionBuildServiceProvider方法来获得。 IServiceCollectionStartup class 中 ConfigureServices 方法的参数。它似乎被框架用 IServiceCollection 的实例神奇地调用了。

我想创建一个 IServiceProvider 的实例,而根本没有 Setup 方法。我需要它来解决集成测试程序集中的依赖关系。有没有可能在这种情况下得到它?

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

查看代码,您应该可以通过调用获得 IServiceCollection

var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();

希望对您有所帮助:)

正如 goaty 提到的那样,足以创建新的 ServiceCollection。这是可用于访问 .NET Core 中的 DI 容器的示例 class:

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取自测试项目,所以服务注册不需要重复。

然后在测试中 class 只需使用:

var foo = ServiceProviderFactory.ServiceProvider.GetServices(typeof(IFoo));

首先你需要安装 Microsoft.Extensions.DependencyInjection NuGet package. (docs, API, API)

然后您创建一个新的 ServiceCollection and method chain it with the BuildServiceProvider 方法。在此期间,您还可以注册任何服务提供商。

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

这是一个更新的方法:

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

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

访问 ASP.NET 核心应用程序的现有 DI,例如在某些控制器中,您应该只在构造函数中解析它。一些经理和工人的例子:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
   services.AddMvc();

   services.AddSingleton<IFooManager, FooManager>();
   services.AddTransient<IFooWorker, FooWorker>();
}

为经理手动解析工人:

public class FooManager: IFooManager
{
    private readonly IServiceProvider _serviceProvider;

    public FooManager(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public void Start()
    {
        var w1 = _serviceProvider.GetRequiredService<IFooWorker>();  // new instance of FooWorker
        var w2 = _serviceProvider.GetRequiredService<IFooWorker>();  // new instance of FooWorker
    }
}

使用这个 ServiceProviderA = new ServiceCollection(). . . . . .BuildServiceProvider() .GetRequiredService<IServiceProvider>(); 此 ServiceProviderA 包含自身