Dependency injection IoC和动态对象
我很难理解如何解析依赖于运行时非确定性创建的对象的对象。最好的方法是什么 想象一下类似文字处理器的东西。对于打开的每个文档,可能需要创建大量依赖于该文档对象的对象 例如,您希望获得DocumentEditor的实例:Dependency injection IoC和动态对象,dependency-injection,inversion-of-control,Dependency Injection,Inversion Of Control,我很难理解如何解析依赖于运行时非确定性创建的对象的对象。最好的方法是什么 想象一下类似文字处理器的东西。对于打开的每个文档,可能需要创建大量依赖于该文档对象的对象 例如,您希望获得DocumentEditor的实例: public class DocumentEditor { public DocumentEditor(IDocument document, ISpellChecker spellChecker,
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.Resolve();
这种方法的缺点是容器到处泄漏
(作为旁注,在unity中实现这一点有点棘手。请参见示例:)
混合方法
应该可以通过实现DocumentEditorFactory来将两者结合起来,DocumentEditorFactory创建嵌套容器并使用子容器来解析依赖关系
最好的分析瘫痪…尝试方法:您可以将所有的拼写检查器和字计数器作为所谓的扩展,这些扩展实现sayIDocumentEditorExtension
接口,并在运行时查询(伪代码):
IDocumentEditor editor=Registry.Resolve();
IDocumentEditorExtension[]extensions=Registry.ResolveAll();
extensions.ForEach((e)=>e.AttachTo(editor));
在autofac中,有一种方法称为。它有点类似于您的第一个选项,但是删除了大量的手工编码。我建议您尝试一下,因为它在这些跟踪问题上非常成熟。您将服务注册到ContainerBuilder,并且您构建的容器根据其范围跟踪您请求的对象。在处置容器时,将处置标有ContainerScoped
的每个对象。因此,您可以为每个DocumentEditor
创建一个容器,并在不再需要文档时处置容器
使用被注射的工厂
这种方法的问题在于
你可以为每个人都建立一个工厂
您需要创建的类型
这是一个关于依赖注入的常见神话。简而言之:您只需要为每个生命周期创建一个工厂,而不是为每个类型创建一个工厂。阅读相关文章。但是,我看不出所描述的方法在这种情况下是如何工作的。我是否有一个DocumentLifetimeFactory,可以创建DocumentEditor、iCellChecker和IWordCounters?这就是我试图利用容器的目的。是的,我会这样做。DocumentLifetimeFactory将创建文档编辑器。您是否需要独立于DocumentEditor创建iCellChecker和IWordCounters?如果是这样的话,DocumentLifetimeFactory也可以创建它们。我应该提到的是,我从未使用过Unity框架,我不知道它是如何工作的。如果Unity框架对你的工厂提出了一些我不熟悉的额外要求,也许你不能像我描述的那样整合你的工厂。容器就是那个工厂。若您添加一些创建实例的工厂,那个么只需将容器的功能加倍。这是一种错误的做法@Andreas需要一种使用容器动态创建对象的方法。我同意Rashack的观点,Autofac具有这样的功能,在这样的场景中非常有用——委托工厂。
var child = container.CreateChildContainer();
child.RegisterInstance<IDocument>(theDocument);
child.Resolve<DocumentEditor>();
IDocumentEditor editor = Registry.Resolve<IDocumentEditor>();
IDocumentEditorExtension[] extensions = Registry.ResolveAll<IDocumentEditorExtension>();
extensions.ForEach((e) => e.AttachTo(editor));