打破.NET MEF导入链

时间:2011-09-01 20:54:08

标签: c# .net mef prism-4

对于此示例,您可以假设顶级正在导入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");
}

2 个答案:

答案 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