【问题标题】:Is MEF a Service locator?MEF 是服务定位器吗?
【发布时间】:2012-06-24 07:44:24
【问题描述】:

我正在尝试使用 Caliburn Micro 和 nHibernate 为新的 LOB MVVM 项目设计架构,现在正在研究 DI 和 IOC。

许多引导 Caliburn Micro 的示例都使用 MEF 作为 DI\IOC 机制。

我苦苦挣扎的是,MEF 似乎相当受欢迎,但 Mef [Imports] 注释的想法在我看来就像是另一种风格的服务定位器?

我是否遗漏了有关 MEF 的某些内容,因为我看到的几乎所有示例都没有正确使用它,或者我完全不了解它的使用方式,从而绕过了整个服务定位器问题?

【问题讨论】:

  • 好的,所以我刚刚了解了 [ImportingConstructor] 属性,它可以启用基于“正确”构造函数的 DI。但问题仍然存在,是 MEF+[Imports] = Service Locator = Antipattern?

标签: mef anti-patterns service-locator


【解决方案1】:

MEF 本身不是服务定位器。它可用于实现服务定位器(Silverlight 版本中的CompositionInitializer 实际上是 MEF 中内置的服务定位器),但它也可以直接进行依赖注入。

虽然这些属性对您来说可能“有味道”,但它们本身并不会导致它成为服务定位器,因为您可以使用 [ImportingConstructor] 在创建时注入数据。

请注意,属性实际上并不是使用 MEF 的唯一方法 - 它也可以通过 direct registrationconvention based registration 工作(CodePlex 删除和 .NET 4.5 支持)。

【讨论】:

  • 是的,我知道它本身不是服务定位器(标题可能无法正确描述我的意图),只是我目前正在尝试了解它以及我的所有示例我发现迄今为止主要使用 [Import] 和 [Export] 并且非常简单。在这些示例中将 [Import] 替换为 Singlton IOC.Resolve(),这就是我书中的服务定位器。感谢 cmets Reed,你给了我更多的阅读机会。
【解决方案2】:

我想如果您只是 new 将具有属性导入的部分添加并尝试使用它们,那么您可能会遇到此处描述的一些相同问题:Service Locator is an Anti-Pattern

但实际上,您从容器中获取部件,如果您使用 [Import] 而不使用额外的 allowDefault 属性,则该部件是必需的,如果您要求执行该部件,容器将在您身上炸毁进口。它会在运行时爆炸,是的,但与磨房服务定位器的运行不同,使用测试框架对 MEF 容器进行静态分析相当简单。我已经写过几次了 herehere

在实践中这对我来说不是问题,原因有两个:

  1. 我从容器中取出零件。
  2. 我使用作文测试。
  3. 我正在编写应用程序,而不是框架代码。

【讨论】:

  • 嗨,吉姆,感谢您的意见。我开始感觉到,在我完成一些编码之前,我不会完全掌握 MEF 作为一种架构工具。为了说明我目前缺乏理解,您上面的 cmets 对我来说听起来像:为了解决 IOC\Decoupling 问题,我们使用 MEF 解决了这些问题,但导致组合问题如此复杂,需要实施整个测试框架来解决它们。
  • 并非如此。开始时,测试可帮助您了解一切是如何工作的。在你了解了一切是如何运作的之后,它更多的是关于捕捉愚蠢的错误。如果测试框架的存在确实意味着系统过于复杂,那么对于任何具有测试的系统来说,这意味着什么?不管怎样,我说去试试吧,或者试试别的。 MEF 不是我尝试的第一个组合框架,但它是我目前最喜欢的。
  • 所有真正的 cmets,谢谢 Jim。我很快就会加入。
猜你喜欢
  • 2012-09-09
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-17
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多