我有一个需要依赖注入的类。由于该类已经是另一个抽象的实现,并且它的“兄弟”实现可能不共享相同的依赖项,我试图使用属性注入而不是构造函数注入。
(所有这些类/接口名称仅用于说明目的)
我的 IProvider 抽象:
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 实现(示例表明它没有相同的依赖项):
public class AnotherProviderClass : IProvider
{
// No data dependency here!!
public void ProviderMethod()
{
// Do other stuff here
}
}
示例 IData 抽象和实现:
public interface IData
{
void DataMethod();
}
public class DataClass : IData
{
public void DataMethod();
}
我需要知道的是:如何使用Unity(我选择的IOC容器)将属性依赖项( IData )成功注入 ProviderClass ?
我已尝试过各种Unity注册选项(RegisterType,RegisterInstance,Resolve ...),但我的注入属性总是以NULL结尾。我想要做到这一点,而不仅仅是强制使用随机代码,直到它成功运行。
或者是否有更好的方法将(可选的)依赖项注入“兄弟”类?
顺便提一下,我的初始IProvider实现是通过抽象工厂创建的,所以也许这可能是我应该把这个IData依赖关注的另一个领域(?)
答案 0 :(得分:4)
你仍然应该使用构造函数注入,因为dependencies should hardly ever be optional。
您正试图在IProviderFactory
实施中阻止constructor over-injection,并且您可能不希望将容器注入工厂以防止落入Service Locator anti-pattern。
但是,如果您在Composition Root内定义了IProviderFactory
实施,那么即使您注入容器,也会阻止自己执行服务定位器,因为Service Locator is not about mechanics。
因此,您应该将ProviderFactory
实现定义为尽可能接近Unity配置,它应该如下所示:
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]);
}
}
此实现可以在Unity中注册为singleton。这使您无需在工厂中进行构造函数过度注入,同时远离服务定位器。