依赖注入,带参数注入

Dependency injection, inject with parameters

我正在使用 DI 的 vNext 实现。 如何将参数传递给构造函数? 例如,我有 class:

public class RedisCacheProvider : ICacheProvider
{
    private readonly string _connectionString;

    public RedisCacheProvider(string connectionString)
    {
        _connectionString = connectionString;
    }
    //interface methods implementation...
}

和服务注册:

services.AddSingleton<ICacheProvider, RedisCacheProvider>();

RedisCacheProvider 的构造函数如何传参class? 例如,对于 Autofac:

builder.RegisterType<RedisCacheProvider>()
       .As<ICacheProvider>()
       .WithParameter("connectionString", "myPrettyLocalhost:6379");

您可以提供一个委托来手动实例化您的缓存提供程序或直接提供一个实例:

services.AddSingleton<ICacheProvider>(provider => new RedisCacheProvider("myPrettyLocalhost:6379"));

services.AddSingleton<ICacheProvider>(new RedisCacheProvider("myPrettyLocalhost:6379"));

请注意,容器不会显式处理手动实例化的类型,即使它们实现了 IDisposable。有关详细信息,请参阅有关 Disposal of Services 的 ASP.NET 核心文档。

如果构造函数也有应该由 DI 解决的依赖项,您可以使用它:

public class RedisCacheProvider : ICacheProvider
{
    private readonly string _connectionString;
    private readonly IMyInterface _myImplementation;

    public RedisCacheProvider(string connectionString, IMyInterface myImplementation)
    {
        _connectionString = connectionString;
        _myImplementation = myImplementation;
    }
    //interface methods implementation...
}

Startup.cs:

services.AddSingleton<IMyInterface, MyInterface>();
services.AddSingleton<ICacheProvider>(provider => 
    RedisCacheProvider("myPrettyLocalhost:6379", provider.GetService<IMyInterface>()));

晚会有点晚了,但是您可以通过 DI 注入一个工厂来创建并公开您的提供程序实例 class。

您可以使用:

 services.AddSingleton<ICacheProvider>(x =>
      ActivatorUtilities.CreateInstance<RedisCacheProvider>(x, "myPrettyLocalhost:6379"));

依赖注入:ActivatorUtilities 将向您的 class.

注入任何依赖

这是 MS 文档的 link:Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance

另外:有关详细信息,请参阅 @poke's answer 。基本上它从提供的服务和你传递的任何其他参数中提取,就像一个复合构造函数。

您可以使用类似下面的示例代码。

经理class:

public class Manager : IManager
{
    ILogger _logger;
    IFactory _factory;
    public Manager(IFactory factory, ILogger<Manager> logger)
    {
        _logger = logger;
        _factory = factory;
    }
}

Startup.cs class:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IFactory, Factory>(sp =>
    {
        var logger = sp.GetRequiredService<ILogger<Factory>>();
        var dbContext = sp.GetRequiredService<MyDBContext>();
        return new Factory(dbContext, logger);
    });
    services.AddTransient<IManager, Manager>(sp =>
    {
        var factory = sp.GetRequiredService<IFactory>();
        var logger = sp.GetRequiredService<ILogger<Manager>>();
        return new Manager(factory, logger);
    });
}

您可以在此处阅读完整示例:DI in Startup.cs in .Net Core