C# 打破.NET MEF导入链

C# 打破.NET MEF导入链,c#,.net,mef,prism-4,C#,.net,Mef,Prism 4,对于本例,您可以假设toplevel正在导入ClassA。只要您导入所有内容(如ClassX),MEF似乎工作得很好。通常不需要导入,因为classB位于同一名称空间/文件中。因此,导入链现在已断开,myLog导入永远不会合成。在我的示例中,ClassB试图导入一个日志服务,这是几乎所有类都可能需要的 哪一种(如有)是解决此问题的预期/最佳MEF解决方案 1) 一旦导入链断开,就不要再使用导入。相反,您必须开始创建/将所有类型传递给构造函数(即新的ClassB(myLog))。这在本例中有效,但

对于本例,您可以假设toplevel正在导入ClassA。只要您导入所有内容(如ClassX),MEF似乎工作得很好。通常不需要导入,因为classB位于同一名称空间/文件中。因此,导入链现在已断开,myLog导入永远不会合成。在我的示例中,ClassB试图导入一个日志服务,这是几乎所有类都可能需要的

哪一种(如有)是解决此问题的预期/最佳MEF解决方案

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

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

3) 回到顶层调用ComposeParts(ClassB)。为了防止toplevel依赖于ClassB,我可以让ClassB实现一个接口(IComposeMe),toplevel导入该接口。然后toplevel将在容器上为所有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");
}

当然,您可以在某个地方注册要导入/导出的类型,而无需扫描整个程序集。 我不知道这是否有帮助,但我在谷歌搜索了一下后发现了一个链接:

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

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


将容器作为全局对象公开本质上是服务定位器模式。不过也有一些问题。

你的回答很有用,但与我的问题无关。您的主题/链接涉及通过注册类型来减少容器中的部件数量。我修改了我的问题和代码示例,以便更好地说明我的问题。我需要在没有导出属性(不是导入链的一部分)的类中满足导入。