虽然回复晚了,但这个问题仍然出现在谷歌搜索中。
无论如何,5年之后...
我的方法相当简单。通常情况下,当您需要使用“命名依赖项”时,是因为您正在尝试实现某种策略模式。在这种情况下,我会在Unity和我的代码之间创建一个间接层,称为StrategyResolver
,以避免直接依赖于Unity。
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
使用方法:
public class SomeClass: ISomeInterface
{
private IStrategyResolver strategyResolver;
public SomeClass(IStrategyResolver stratResolver)
{
this.strategyResolver = stratResolver;
}
public void Process(SomeDto dto)
{
IActionHandler actionHanlder = this.strategyResolver.Resolve<IActionHandler>(dto.SomeProperty);
actionHanlder.Handle(dto);
}
}
注册:
container.RegisterType<IActionHandler, ActionOne>("One");
container.RegisterType<IActionHandler, ActionTwo>("Two");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<ISomeInterface, SomeClass>();
现在,这件事的好处是,当我将来添加新策略时,我永远不必再去触碰StrategyResolver。
这很简单。非常干净,而且我将对Unity的依赖保持到最低限度。唯一需要触碰StrategyResolver的时间是如果我决定更改容器技术,这种情况非常不可能发生。
希望这可以帮助你!
编辑:我并不真的喜欢接受的答案,因为当你在服务的构造函数中使用Dependency属性时,你实际上对Unity有了一个硬依赖。Dependency属性是Unity库的一部分。此时,你也可以在任何地方传递IUnityContainer依赖。
我更喜欢我的服务类依赖于我完全拥有的对象,而不是在各个地方都有对外部库的强依赖。而且使用Dependency属性会使构造函数的签名变得不那么清晰和简单。
此外,这种技术允许在运行时解析命名依赖项,而无需在构造函数中硬编码命名依赖项,在应用程序配置文件中使用它们或使用InjectionParameter,这些方法都需要在设计时知道要使用哪个命名依赖项。
编辑(2016-09-19):
对于那些可能会想知道的人,当您请求IUnityContainer作为依赖项时,容器将知道传递自己,如StrategyResolver构造函数签名所示。
编辑(2018-10-20):
这里是另一种方法,简单地使用工厂:
public class SomeStrategyFactory : ISomeStrategyFactory
{
private IStrategy _stratA;
private IStrategy _stratB;
public SomeFactory(IStrategyA stratA, IStrategyB stratB)
{
_stratA = stratA;
_stratB = stratB;
}
public IStrategy GetStrategy(string namedStrategy){
if (namedStrategy == "A") return _stratA;
if (namedStrategy == "B") return _stratB;
}
}
public interface IStrategy {
void Execute();
}
public interface IStrategyA : IStrategy {}
public interface IStrategyB : IStrategy {}
public class StrategyA : IStrategyA {
public void Execute(){}
}
public class StrategyB : IStrategyB {
public void Execute() {}
}
使用方法:
public class SomeClass : ISomeClass
{
public SomeClass(ISomeStrategyFactory strategyFactory){
IStrategy strat = strategyFactory.GetStrategy("HelloStrategy");
strat.Execute();
}
}
注册:
container.RegisterType<ISomeStrategyFactory, SomeStrategyFactory>();
container.RegisterType<IStrategyA, StrategyA>();
container.RegisterType<IStrategyB, StrategyB>();
container.RegisterType<ISomeClass, SomeClass>();
这第二个建议与第一个相同,只是使用了工厂设计模式。
希望对您有所帮助!
IRepository< Customer >("Customer")
应该被注入到另一个ClientModel
实例中。 - Legends