依赖注入,带参数注入
Posted
技术标签:
【中文标题】依赖注入,带参数注入【英文标题】:Dependency injection, inject with parameters 【发布时间】:2016-01-17 02:01:16 【问题描述】:我正在使用 DI 的 vNext 实现。 如何将参数传递给构造函数? 例如,我有课:
public class RedisCacheProvider : ICacheProvider
private readonly string _connectionString;
public RedisCacheProvider(string connectionString)
_connectionString = connectionString;
//interface methods implementation...
和服务注册:
services.AddSingleton<ICacheProvider, RedisCacheProvider>();
如何将参数传递给 RedisCacheProvider 类的构造函数? 以 Autofac 为例:
builder.RegisterType<RedisCacheProvider>()
.As<ICacheProvider>()
.WithParameter("connectionString", "myPrettyLocalhost:6379");
【问题讨论】:
我的通用解决方案:gist.github.com/ReallyLiri/c669c60db2109554d5ce47e03613a7a9 相关帖子 - .NET Core DI, ways of passing parameters to constructor 【参考方案1】:您可以提供一个委托来手动实例化您的缓存提供程序,也可以直接提供一个实例:
services.AddSingleton<ICacheProvider>(provider => new RedisCacheProvider("myPrettyLocalhost:6379"));
services.AddSingleton<ICacheProvider>(new RedisCacheProvider("myPrettyLocalhost:6379"));
请注意,容器不会显式处理手动实例化的类型,即使它们实现了 IDisposable。有关详细信息,请参阅有关 Disposal of Services 的 ASP.NET Core 文档。
【讨论】:
简单实用 不要忘记如果你的服务接受了你注册的其他参数,你可以在注册的时候传递一个引用到你的服务。例如如果“RedisCacheProvider”也需要 ISomeService,你可以这样做:services.AddSingletonAddSingleton<T>(T)
注册类型,那将是一件好事。从注册代表返回的类型(例如使用AddSingleton<T>(Func<IServiceProvider, T>)
)实际上将被丢弃。
如果我有另一个 ICacheProvider 实现,我该如何处理?【参考方案2】:
如果构造器还具有应该由 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>()));
【讨论】:
【参考方案3】:你可以使用:
services.AddSingleton<ICacheProvider>(x =>
ActivatorUtilities.CreateInstance<RedisCacheProvider>(x, "myPrettyLocalhost:6379"));
依赖注入:ActivatorUtilities 会将任何依赖注入到您的类中。
这是 MS 文档的链接:Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance
另外:请参阅@poke 的答案here 了解更多信息。基本上它从提供的服务和您传递的任何其他参数中提取,例如复合构造函数。
【讨论】:
【参考方案4】:您可以使用下面的示例代码。
经理类:
public class Manager : IManager
ILogger _logger;
IFactory _factory;
public Manager(IFactory factory, ILogger<Manager> logger)
_logger = logger;
_factory = factory;
Startup.cs 类:
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
【讨论】:
【参考方案5】:聚会有点晚了,但您可以 DI 注入一个工厂,该工厂创建并公开您的提供程序类的实例。
【讨论】:
以上是关于依赖注入,带参数注入的主要内容,如果未能解决你的问题,请参考以下文章