C# 使用Unity进行属性依赖项注入的正确方法
我有一个类需要依赖注入。由于该类已经是另一个抽象的实现,并且它的“兄弟”实现可能不共享相同的依赖项,因此我尝试使用属性注入,而不是构造函数注入 (所有这些类/接口名称仅用于说明) 我的IProvider摘要:C# 使用Unity进行属性依赖项注入的正确方法,c#,dependency-injection,unity-container,ioc-container,C#,Dependency Injection,Unity Container,Ioc Container,我有一个类需要依赖注入。由于该类已经是另一个抽象的实现,并且它的“兄弟”实现可能不共享相同的依赖项,因此我尝试使用属性注入,而不是构造函数注入 (所有这些类/接口名称仅用于说明) 我的IProvider摘要: public interface IProvider { void ProviderMethod(); } 我的IProvider实现(带有我想要注入的IData依赖项): public class ProviderClass : IProvider { // How d
public interface IProvider
{
void ProviderMethod();
}
我的IProvider实现(带有我想要注入的IData依赖项):
public class ProviderClass : IProvider
{
// How do I inject this dependency?
[Dependency]
public IData data { get; set; }
public void ProviderMethod()
{
// Can't do this as data == null!
data.DataMethod();
}
}
另一个IProvider实现(示例显示它没有相同的依赖项):
IData抽象和实现示例:
public interface IData
{
void DataMethod();
}
public class DataClass : IData
{
public void DataMethod();
}
我需要知道的是:如何使用Unity(我选择的IOC容器)成功地将属性依赖项(IData)注入ProviderClass
我尝试了所有的Unity注册选项(RegisterType、RegisterInstance、Resolve…),但是我的注入属性总是以NULL结束。我想把这件事做好,而不是强迫随机代码进入,直到它能够正常工作
或者有没有更好的方法将(可选)依赖项注入到“兄弟”类中
顺便说一句,我最初的IProvider实现是通过一个抽象工厂创建的,所以这可能是我应该关注IData依赖的另一个领域(?)您仍然应该使用构造函数注入,因为 您正试图在
IProviderFactory
实现中进行阻止,您可能不想将容器注入工厂以防止落入容器
但是,如果您在内部定义了IProviderFactory
实现,则会阻止自己执行服务定位器,即使您注入了容器,因为
因此,您应该尽可能靠近Unity配置来定义您的ProviderFactory
实现,它应该如下所示:
public class ProviderFactory : IProviderFactory
{
private readonly Dictionary<string, Type> providerTypes;
private readonly Container container;
public ProviderFactory(Dictionary<string, Type> providerTypes,
Container container) {
this.providerTypes = providerTypes;
this.container = container;
}
public IProvider CreateProvider(string name) {
return (IProvider)this.container.Resolve(this.providerTypes[name]);
}
}
公共类ProviderFactory:IPProviderFactory
{
专用只读词典提供程序类型;
专用只读容器;
公共ProviderFactory(字典providerTypes,
集装箱(集装箱){
this.providerTypes=providerTypes;
this.container=容器;
}
公共IProvider CreateProvider(字符串名称){
返回(IPProvider)this.container.Resolve(this.providerTypes[name]);
}
}
此实现可以在Unity中注册为singleton。这使您不必在远离服务定位器的情况下向工厂过度注入构造函数。您仍然应该使用构造函数注入,因为 您正试图在
IProviderFactory
实现中进行阻止,您可能不想将容器注入工厂以防止落入容器
但是,如果您在内部定义了IProviderFactory
实现,则会阻止自己执行服务定位器,即使您注入了容器,因为
因此,您应该尽可能靠近Unity配置来定义您的ProviderFactory
实现,它应该如下所示:
public class ProviderFactory : IProviderFactory
{
private readonly Dictionary<string, Type> providerTypes;
private readonly Container container;
public ProviderFactory(Dictionary<string, Type> providerTypes,
Container container) {
this.providerTypes = providerTypes;
this.container = container;
}
public IProvider CreateProvider(string name) {
return (IProvider)this.container.Resolve(this.providerTypes[name]);
}
}
公共类ProviderFactory:IPProviderFactory
{
专用只读词典提供程序类型;
专用只读容器;
公共ProviderFactory(字典providerTypes,
集装箱(集装箱){
this.providerTypes=providerTypes;
this.container=容器;
}
公共IProvider CreateProvider(字符串名称){
返回(IPProvider)this.container.Resolve(this.providerTypes[name]);
}
}
此实现可以在Unity中注册为singleton。这使您不必在远离服务定位器的情况下向工厂过度注入构造函数。我不清楚您为什么不进行构造函数注入。你能详细说明一下吗?主要是因为依赖项是可选的,其他IProvider实现可能有许多自己的依赖项,这些依赖项对于它们的类来说是唯一的。IProvider实现从抽象工厂(比如IProviderFactory)返回;随着每个新的IProvider实现的添加,工厂将不得不在其自己的注入策略中适应它们不断增长的数量(潜在的构造函数参数膨胀?)。使用Unity进行属性依赖项注入的正确方法是:让解析的类型包含正确的配置,而不要重复自己。例如,如果您需要横切关注点来将日志注入多个对象,您可以使用拦截器。我不清楚为什么不进行构造函数注入。你能详细说明一下吗?主要是因为依赖项是可选的,其他IProvider实现可能有许多自己的依赖项,这些依赖项对于它们的类来说是唯一的。IProvider实现从抽象工厂(比如IProviderFactory)返回;随着每个新的IProvider实现的添加,工厂将不得不在其自己的注入策略中适应它们不断增长的数量(潜在的构造函数参数膨胀?)。使用Unity进行属性依赖项注入的正确方法是:让解析的类型包含正确的配置,而不要重复自己。例如,如果您需要横切关注点将日志记录注入多个对象,则可以使用拦截器。