打破.net MEF导入链

本文关键字:导入 MEF net 打破 | 更新日期: 2023-09-27 18:07:21

对于本例,您可以假设top正在导入ClassA。MEF似乎工作得很好,只要你导入一切(即ClassX)。通常不需要导入,因为classB位于相同的命名空间/文件中。因此,导入链现在被打破,myLog导入永远不会组成。在我的例子中,ClassB试图导入一个Logger Service,这是几乎所有类都想要的。

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

1)一旦import链被打破,永远不要再使用import。相反,你必须开始创建/传递所有类型给构造函数(例如:新ClassB (myLog))。这在本例中有效,但如果链中有中间类没有使用参数,则会很混乱。

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

3)回到顶层调用ComposeParts(ClassB)。为了防止顶层依赖于类b,我可以让类b实现一个由顶层导入的接口(IComposeMe)。然后顶层将在容器上为所有IComposeMe导入compospart。我不认为这是预期的解决方案,因为它没有在MEF框架文档中描述或使用。

我实在想不出主意了,请帮帮我…

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");
}

打破.net MEF导入链

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

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

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

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