对于此示例,您可以假设顶级正在导入ClassA。只要您导入所有内容(即ClassX),MEF似乎效果很好。通常您不需要导入,因为classB位于相同的命名空间/文件中。结果导入链现在被破坏,myLog导入从未被编写。在我的示例中,ClassB尝试导入Logger服务,这几乎是所有类可能都需要的。
哪个是针对此问题的预期/最佳MEF解决方案?
1)一旦导入链断开,再也不要使用import。相反,您必须开始创建/传递所有类型到构造函数(即新的ClassB(myLog))。这适用于此示例,但如果链中存在不使用参数的中间类,则会很混乱。
2)使用System命名空间中的IServiceLocator导入ClassB。据我所知,ServiceLocator(例如Prism Framework)仅用于抽象依赖注入方案。对于此示例,如果ClassB可以导入IServiceLocator,那么它可以导入ILogger。
3)回到顶层调用ComposeParts(ClassB)。为了防止顶层依赖于ClassB,我可以让classB实现一个接口(IComposeMe),它是toplevel导入的。然后,对于所有IComposeMe导入,容器上的ComposeParts将是ComposeParts。我不相信这是预期的解决方案,因为它没有在MEF框架文档中描述或使用。
4)其实我没有想法,请帮忙......
class ClassA {
// Imports within ClassX will get composed
[Import]
ClassX myClassX;
// Imports within ClassB will NOT be composed!
var myClassB = new ClassB
}
class ClassB {
// Fails because ClassB is never Composed
[Import]
ILogger myLog;
myLog.Display("Hello World");
}
[Export]
class ClassX {
// Works - Imports are satified when ClassX imported
[Import]
ILogger myLog;
myLog.Display("Hello World");
}
答案 0 :(得分:1)
如果您遵循依赖注入模式,首选方法是什么? 不要破坏导入链。您的应用程序中应该有一个组合根,其中组件连接在一起。组件本身不应该关心获取它们的依赖关系。
当然,在实践中你必须处理现有代码(以及其他对DI持怀疑态度的开发人员),因此你不能总是“一直向下”进行依赖注入。在这些情况下,您可以将容器公开为全局变量,并从中拉出必要的依赖项。
将容器公开为全局本质上是服务定位器模式。它虽然有一些disadvantages。
答案 1 :(得分:0)
当然,您可以在某个地方注册要导入/导出的类型,而无需扫描整个装配体。 我不知道这是否会有所帮助,但这是我在google搜索后发现的一个链接: http://blogs.microsoft.co.il/blogs/zuker/archive/2010/10/17/mef-runtime-type-catalog-support-multi-registrations-in-runtime.aspx