MEF与任何IoC


69

从Microsoft的Managed Extensibility Framework(MEF)和各种IoC容器(例如Unity)来看,我看不到何时使用一种解决方案。更具体地说,似乎MEF可以处理大多数IoC类型模式,而像Unity这样的IoC容器则不是必需的。

理想情况下,我希望看到一个很好的用例,其中将使用IoC容器代替MEF或作为MEF的补充。


Answers:


75

归结起来,主要区别在于IoC容器通常对静态依赖项最有用(在编译时已知),而MEF通常对动态依赖项最有用(仅在运行时知道)。

因此,它们都是合成引擎,但是每种模式的重点都非常不同。因此,由于MEF围绕发现未知零件(而不是已知零件的注册)进行了优化,因此设计决策大相径庭。

这样考虑:如果您正在开发整个应用程序,则IoC容器可能是最好的。如果您正在编写可扩展性,例如第三方开发人员将扩展您的系统,那么MEF可能是最好的。

另外,@ Pavel Nikolov的答案中的文章提供了一些很好的指导(由MEF的项目经理Glenn Block撰写)。


2
MSDN上的这篇文章的确为我提供了帮助:msdn.microsoft.com/en-us/library/hh708870.aspx。对于熟悉IoC / ID的MEF新手来说,MEF似乎是注入(组成)...没有类型注册。因此,上述SO答案确实为我指出了要点。现在收听备受吹捧的Hanselman播客专题集:hanselminutes.com/148/…– NovaJoe
2012年

请指出一些特定的示例,其中任何IoC在静态依赖项(在编译时已知)下都比MEF更有用。我发现Export \ Import Attributes或Registration Builder对于静态依赖项比复杂的易于出错的配置文件有用得多。
亚伦·斯坦巴克

1
@AaronStainback:我选择的容器是Autofac,它比基于文件的注册更喜欢配置文件,类似于Registration Builder(我不喜欢XML)。与MEF相比,Autofac的优势包括:通过lambda表达式注册,细粒度的生命周期控制以及对组合的了解(组合类型对Autofac或使用它们的上下文一无所知)。当您控制组合类型时,这些方面是最有利的,因此Autofac和MEF之间的重点有所不同。两者之间的维恩图通常涵盖更简单的DI场景。
布莱恩·瓦茨

@AaronStainback:另外,请为不正确或误导性的答案保留下注,而不是反映个人喜好。缺乏支持可以传达这一点。
布莱恩·瓦茨

@BryanWatts:反对票不是出于个人喜好,而是出于主观回答而未提供任何事实。您在答复中指出的项目本来会很有帮助,尽管它们并非100%准确。.NET 4.5中的MEF 2.0具有成分模糊性,因此我不认为这是一个优势。同样,MEF也通过lambda表达式进行注册,因此一个也是平局。MEF还在.NET 4.5中添加了一些更细粒度的生命周期管理。Autofac具有更多内置的生命周期策略,但MEF提供了构建策略。
亚伦·斯坦巴克

26

我已经使用MEF一段时间了,使用MEF代替IOC产品的关键因素是,在给定的时间,我们通常在插件目录中有3-5个给定接口的实现。实际上应该使用那些实现中的哪一个只能在运行时确定。

MEF擅长让您做到这一点。通常,IOC的目标是确保将来某个时候可以将基于ORM产品1的IUserRepository换为ORM产品2。但是,大多数IOC解决方案都假定在给定时间只有一个IUserRepository有效。

但是,如果您需要根据给定页面请求的输入数据选择一个,则IOC容器通常会不知所措。

举例来说,我们通过MEF插件对我已经工作了一段时间的大型Web应用程序进行了权限检查和验证。使用MEF,我们可以查看记录的CreatedOn日期,并挖掘创建记录时实际上有效的验证插件,然后通过该插件和当前有效的验证器运行记录,并比较记录的有效性。时间。

这种功能还使我们能够定义插件的穿透替代。我正在使用的应用实际上是为30多个实现部署的相同代码库。因此,我们通常会通过以下方式寻找插件:

  1. 特定于当前站点和特定记录类型的接口实现。
  2. 一个特定于当前站点的接口实现,但可用于任何类型的记录。
  3. 适用于任何站点和任何记录的界面。

这使我们可以捆绑一组将插入的默认插件,但前提是该特定实现未使用客户特定规则覆盖它。

IOC是一项伟大的技术,但实际上似乎更多的是要简化对接口的编码,而不是具体的实现。但是,在IOC中,换掉这些实现更多的是项目转移。在MEF中,您可以灵活地使用接口和具体实现,并在许多可用选项之间做出运行时决策。


我喜欢通过MEF应用多个验证的示例。
David Keaveny

5

我很抱歉失去话题。我只想说有2个缺陷使MEF成为不必要的麻烦:

  • 它是基于属性的,对帮助您弄清事物为何如此起作用没有任何帮助。没有办法了解框架内部的细节,以了解到底发生了什么。无法获取跟踪日志或连接到解决机制并手动处理未解决的情况

  • 它没有任何故障排除机制来找出某些零件被拒绝的原因。尽管指向了失败的部分,但它并没有告诉您为什么该部分失败了。

因此,我对此感到非常失望。我花了很多时间与风车战斗,试图重新启动几节课,而不是着手解决实际问题。我坚信,当您完全控制VS调试器中的创建内容,创建时间和跟踪内容时,没有什么比老式的依赖注入技术更好了。我希望提倡MEF的人提出了很多充分的理由,说明为什么我会选择它而不是普通的DI。


1

我同意MEF可以成为功能完善的IoC框架。实际上,我现在正在基于将MEF用于可扩展性和IoC来编写应用程序。我将它的通用部分放入一个“框架”中,并将其作为名为SoapBox Core的自己的框架开源,以防人们想知道它是如何工作的。

特别是,如果您想查看MEF的运行情况,请看一下主机如何工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.