2

对于此示例,您可以假设顶层正在导入 ClassA。只要您导入所有内容(即 ClassX),MEF 似乎就可以很好地工作。通常你不需要导入,因为 classB 在同一个命名空间/文件中。结果,导入链现在被破坏,并且 myLog 导入永远不会被组合。在我的示例中,ClassB 正在尝试导入 Logger Service,这几乎是所有类都希望的。

如果有的话,哪个是该问题的预期/最佳 MEF 解决方案?

1)一旦导入链被破坏,永远不要再使用导入。相反,您必须开始创建/将所有类型传递给构造函数(即 new ClassB(myLog))。这在此示例中有效,但如果链中存在未使用参数的中间类,则会很混乱。

2)利用System命名空间中的IServiceLocator导入ClassB。据我所知,ServiceLocator(例如 Prism 框架)的存在只是为了抽象依赖注入方案。对于此示例,如果 ClassB 可以导入 IServiceLocator,那么它可以导入 ILogger。

3) 回到顶层调用 ComposeParts(ClassB)。为了防止顶层依赖于 ClassB,我可以让 classB 实现顶层导入的接口 (IComposeMe)。然后顶层将 ComposeParts 在容器上用于所有 IComposeMe 导入。我不认为这是预期的解决方案,因为 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");
}
4

2 回答 2

1

如果您遵循依赖注入模式,首选方法是什么?不要破坏进口链。您的应用程序中应该有一个组合根,其中组件连接在一起。组件本身不应该关心获取它们的依赖关系。

诚然,在实践中,您必须处理现有代码(以及其他对 DI 持怀疑态度的开发人员),因此您不能总是“一路向下”进行依赖注入。在这些情况下,您可以将容器公开为全局变量并从那里提取必要的依赖项。

将容器公开为全局本质上是服务定位器模式。虽然它有一些缺点

于 2011-09-01T22:58:41.740 回答
0

当然,您可以在某处注册要导入/导出的类型,而无需扫描整个程序集。我不知道这是否会有所帮助,但这是我在谷歌搜索后发现的一个链接:http: //blogs.microsoft.co.il/blogs/zuker/archive/2010/10/17/mef-runtime-type-目录支持-多注册-在-runtime.aspx

于 2011-09-01T21:10:03.790 回答