我无法弄清楚如何解析依赖于在运行时非确定性创建的对象的对象。什么是最好的方法?
想象一下像文字处理器这样的东西。对于打开的每个文档,您可能希望创建大量依赖于文档对象的对象。
例如,您希望获得DocumentEditor的实例:
public class DocumentEditor {
public DocumentEditor(IDocument document,
ISpellChecker spellChecker,
IWordCounter wordCounter) {
...
}
}
到目前为止,我已经考虑了两种方法,但似乎都不合适:
这种方法的问题在于,您最终可能需要为每种类型创建工厂。即。
public interface ISpellCheckerFactory {
ISpellChecker Create(IDocument document);
}
public interface IWordCounterFactory {
IWordCounter Create(IDocument document);
}
public class DocumentEditorFactory {
public DocumentEditorFactory(ISpellCheckerFactory spellCheckerFactory,
IWordCounterFactory wordCounterFactory) {
...
}
public DocumentEditor Create(IDocument document) {
...
}
}
添加另外50个课程,你会看到问题......
使用嵌套容器无需创建数百个工厂。它实际上非常紧凑(使用Unity的例子):
var child = container.CreateChildContainer();
child.RegisterInstance<IDocument>(theDocument);
child.Resolve<DocumentEditor>();
这种方法的缺点是容器在整个地方都会泄漏。
(作为旁注,统一实施这有点棘手。例如:见How to register types in the main container, but resolve in a child container?)
应该可以通过实现创建嵌套容器的DocumentEditorFactory并使用子容器来解析依赖关系来组合这两者。
分析瘫痪最好......
答案 0 :(得分:1)
在autofac中有一种名为DelegateFactories的方法。它有点类似于你的第一个选项,但删除了大量的手工编码。
答案 1 :(得分:0)
我建议您尝试AutoFac,因为它在这些跟踪问题上非常成熟。您将服务注册到ContainerBuilder,并且您构建的容器会根据其范围跟踪您请求的对象。标记为ContainerScoped
的每个对象将在处置容器时处理。因此,您可以为每个DocumentEditor
创建一个容器,并在不再需要文档时配置容器。
答案 2 :(得分:0)
使用注入的工厂
这种方法的问题在于 你最终可以找到一个工厂 你需要创建的类型。
这是关于依赖注入的常见神话。 I highly recommend Misko Hevery's article regarding the new operator。简而言之:您只需要为每个生命周期创建一个工厂,而不是为每种类型创建一个工厂。
答案 3 :(得分:-1)
尝试MEFy方法:您可以将所有SpellChecker
和WordCounter
作为所谓的扩展,实现说IDocumentEditorExtension
接口并在运行时查询(伪代码):
IDocumentEditor editor = Registry.Resolve<IDocumentEditor>();
IDocumentEditorExtension[] extensions = Registry.ResolveAll<IDocumentEditorExtension>();
extensions.ForEach((e) => e.AttachTo(editor));