在MEF和MAF之间选择(System.AddIn)


162

托管扩展框架(MEF)和托管加载项框架(MAF,又名System.AddIn)似乎完成了非常相似的任务。根据这个堆栈溢出问题,MEF是否可以替代System.Addin?,您甚至可以同时使用两者。

您何时选择使用一个与另一个?在什么情况下您会选择同时使用两者?

Answers:


131

我一直在评估这些选项,这就是我得出的结论。

MAF是真正的插件框架。您可以完全分离您的插件,甚至可以在单独的应用程序域中运行它们,这样,如果某个插件崩溃,它就不会关闭您的应用程序。它还提供了一种非常完整的方法来使附加组件脱离耦合,这取决于您提供的合同以外的任何内容。实际上,您可以对合同适配器进行版本控制,以在升级主应用程序时向后兼容旧插件。虽然这听起来不错,但要跨越应用程序域,您必须付出沉重的代价。您为此付出的代价是速度和来回发送类型的灵活性。

MEF更像是依赖项注入,它具有一些其他好处,例如可发现性和...(为此空白)。MAF具有的隔离度在MEF中不存在。它们是针对两个不同事物的两个不同框架。


5
一件事:请记住,如果您的加载项在本机层崩溃,“单独的应用程序域”对您没有帮助,因为您仍然需要辅助进程。MAF在创建它们方面有所帮助,但是要从这种崩溃中进行动态恢复仍然相当困难(但可能)
quetzalcoatl 2012年

@Ian:请重新阅读我的评论:)我已经写完了,而且:MAF确实允许这样做,但是在崩溃之后,您必须自己起床。
quetzalcoatl

@DanielG>要跨越应用程序域,您必须付出沉重的代价<这是为什么?多重'?
Martin Meeser 2014年

2
@MartinMeeser跨应用程序域时,必须序列化所有内容或使用MarshalByRef对象。与在同一应用程序域中的对象之间进行通信相比,通信要困难得多。
Danielg 2014年

65

Danielg所说的很好。我会补充:

如果您观看有关System.Addins的视频,那么他们显然是在谈论非常大的项目。他谈到一个团队管理的主机应用程序,另一个团队管理每个加载项和第三管理合同和管道。基于此,我认为System.Addins显然适用于大型应用程序。我在考虑诸如SAP之类的ERP系统之类的应用程序(可能没有那么大,但是您知道了)。如果您观看了这些视频,则可以知道使用System.Addins的工作量非常大。如果您有很多公司为您的系统编程第三方插件,并且您不能因死刑而违反任何这些插件合同,那将很好用。

另一方面,MEF似乎与SharpDevelop的附加方案,Eclipse插件体系结构或Mono.Addins具有更多相似之处。它比System.Addins容易理解,我相信它会更加灵活。您所失去的是,您没有获得与MEF兼容的AppDomain隔离或强大的版本控制合同。MEF的优势在于您可以将整个应用程序构造为零件组成,因此可以为不同的客户提供不同配置的产品,如果客户购买了新功能,则只需将该功能的零件放到其安装目录中然后应用程序看到它并运行它。它还有助于测试。您可以实例化要测试的对象,并将其所有依赖项提供给模拟对象,

我想提到的最重要的一点是,即使System.Addins已经在框架中,我也没有看到很多人在使用它的证据,但MEF只是被认为包含在CodePlex上。 .NET 4,人们已经开始使用它构建许多应用程序(包括我自己)。我认为这可以告诉您有关这两个框架的信息。


1
“如果您观看有关System.Addin的视频”,哪些视频?您能否提供链接。谢谢
jimjim 2012年


60

已经开发并发布了MAF应用程序。我对MAF的看法有些疲倦。

MAF是最糟糕的“解耦”系统或“松散耦合”系统。MEF充其量是“耦合”系统或“松散耦合”系统。

我们通过使用MAF实现的MAF好处是:

  1. 在应用程序运行时安装新组件或更新现有组件。可以在应用程序运行时更新AddIn,并且更新对用户无缝显示。您必须为此拥有AppDomains。

  2. 根据购买的组件进行许可。我们可以通过用户的角色和权限来控制加载哪个AddIn,以及该AddIn是否已获得使用许可。

  3. 快速发展(更快的上市时间)。AddIn开发非常适合敏捷方法,开发团队一次开发了一个AddIn,而不必同时开发与应用程序其余部分的集成。

  4. 改进的质量检查(一次仅对一个组件进行质量检查)。然后,质量检查人员可以针对单个功能进行测试并发布缺陷。测试用例更易于开发和实施。

  5. 部署(在开发和发布组件时添加组件,它们“可以正常工作”)。部署仅是制作一个插件并安装文件的问题。无需其他考虑!

  6. 新组件与旧组件一起使用。早期开发的AddIn可以继续使用。新的插件可以无缝地集成到应用程序中


3
我已经在.NET 4上用MEF完成了上述所有工作,我认为它比MAF更简单...
Tim

21
@Jim:您可以在运行时卸载现有的MEF加载项吗?据我所知,加载项程序集一旦加载就无法卸载,因为它位于同一AppDomain中。
Scott Whitlock 2010年

6
@Scott-+1(我可以提供多个吗?)此处未列出的另一个好处:您可以使用MAF沙盒化该插件的安全权限,而MEF中组件所使用的安全权限将与运行时共享相同的权限。应用。
道格

2
@ScottWhitlock:您暗示不可能将MEF与多个AppDomain一起使用,这是不正确的。
M.Stramm

25

在我看来,这两种技术实际上针对的是非常不同的用例。

MEF通常是在纯粹的依赖注入方案中最好的方案,在这种方案中,提供最终集成解决方案的人员或团队正在组装所有东西并保证整体完整性,但是需要采用关键功能的不同实现。

MAF适用于某个人/组正在开发平台或主机,而其他组在事后且以不受主机组控制的方式添加功能的场景。在这种情况下,需要更复杂的机制来“保护”主机免受恶意加载项的影响(或防止加载项彼此之间的冲突)。

第三种相似模式技术是整个ProviderBase方案。这也使替换功能成为可能,但其目标实际上是主机/应用程序绝对需要功能并且实际上需要通过config指定不同实现的场景。


18

我刚刚发现这篇冗长的文章同时讨论了MAF和MEF。 http://emcpadden.wordpress.com/2008/12/07/managed-extensibility-framework-and-others/

除了其他答案提出的要点外,MEF和MAF之间的主要区别之一似乎是托管可扩展性框架将允许一个可组合部分依赖另一个。例如,它将使一个插件依赖于另一个插件。

托管扩展框架也没有像System.AddIn那样真正区分主机和外接程序。就MEF而言,它们都是可组合的部分。


9

我认为,发现差异的最佳方法是一些动手代码。我发现了两个MSDN演练,两个演练都有一个计算器示例,因此您可以轻松比较它们的实现:

MEF: 使用简单的计算器例子MEF部分
中号 anaged ê xtensibility ˚F ramework)

  • 展示了如何使用MEF技术构建一个简单的计算器。不显示如何加载外部dll。(但是您可以使用catalog.Catalogs.Add(new DirectoryCatalog("Plugins", "*.dll")); 而不是使用来简单地修改示例, catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));并提取计算器代码和合同以分离DLL项目。)
  • MEF 并不需要有一个特定的目录结构,它是简单和容易使用,即使是小项目。它与属性一起使用,以声明要导出的内容,这易于阅读和理解。例: [Export(typeof(IOperation))] [ExportMetadata("Symbol", '+')] class Add: IOperation { public int Operate(int left, int right) { return left + right; } }

  • MEF不会自动处理版本控制

MAF: 简单的计算器与V1和V2版本MAF插件
中号 anaged 一个 ddin ˚F ramework)

  • 显示如何使用V1插件构建计算器,然后如何在保持向后兼容性的同时移至V2插件(注意:您可以在此处找到该插件的V2版本,原始文章中的链接已断开)
  • MAF 强制执行特定的目录结构,并且需要大量样板代码才能使其正常工作,因此我不建议在小型项目中使用它。 例:
    Pipeline
      AddIns
        CalcV1
        CalcV2
      AddInSideAdapters
      AddInViews
      Contracts
      HostSideAdapters

.NET Framework 4.x中包含MEF和MAF。如果比较这两个示例,您会注意到MAF插件比MEF框架复杂得多-因此您需要仔细考虑何时使用那些框架。


3

MAF和MEF都可以使用AppDomains,并且都可以在运行时加载/卸载dll。但是我发现的区别是:MAF插件解耦,MEF组件松耦合;MAF默认情况下会“激活”(新实例),而MEF会创建实例。

使用MEF,您可以使用Generics来为任何合同创建GenericHost。这意味着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.