我正在处理遗留代码。
我有同一个类的不同方法,它们将不同的参数传递给依赖项的构造函数。我正在尝试引入一些基本的IoC用法。现在我让StructureMap像这样传递我的参数:
var thing = ObjectFactory.GetInstance<IThingInterface>(new ExplicitArguments(
new Dictionary<string, object> {
{ "constructorArgA", notShown },
{ "constructorArgB", redacted.Property } }));
其中为constructorArgA和B传递的实际属性会根据我的位置而改变。
有一种方法可以通过实际类型来配置它,而不是“constructorArgA”,就像配置objectFactory时一样,例如:
x.For<IHidden>().Use<RealType>()
.Ctor<IConfig>().Is(new Func<IContext, IConfig>(
(context) => someMethodToGetIConfig()));
如果我是从头开始编写这个,我可能会将依赖关系构建得有点不同以避免这种情况,但这对我来说不是一个选项。
答案 0 :(得分:3)
这是DI容器的经典/常见问题。
我的第一选择是创建一个“手动”抽象工厂来创建IThingInterface,然后使用Structuremap在需要它的地方注入IThingInterfaceFactory。通过手动工厂,我的意思是调用新的ThingInterface()并返回它。如果你这样做,你的实现将不再是容器管理的,如果它有依赖关系,容器将不再提供它们(可能或可能不是你的问题)
第二种选择是创建一个实际使用/包装容器的抽象工厂。所以基本上是你的第一个代码片段,但是包含在工厂类中,其中Create()方法接受你的参数。这样做的好处是所有内容(包括您的实现及其依赖项)都是容器管理的,但直接引用容器的缺点(这不是最佳实践 - 请参阅Article on Composition Roots)。
你也可以做二传注射,但我个人认为这是最后的手段。
Castle Windsor有一个很好的解决方案(Typed Factory Facility)。不确定是否在选项中切换容器,但您可能会考虑它。