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

时间:2009-05-07 14:59:25

标签: .net add-in mef system.addin maf

Managed Extensibility Framework(MEF)和Managed AddIn Framework(MAF,又名System.AddIn)似乎完成了非常相似的任务。根据此Stack Overflow问题Is MEF a replacement for System.Addin?,您甚至可以同时使用这两个问题。

您何时会选择使用其中一种?在什么情况下你会选择同时使用它们?

7 个答案:

答案 0 :(得分:126)

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

MAF是一个真正的插件框架。您可以完全分离您的插件,甚至可以在单独的应用程序域中运行它们,这样如果插件崩溃,它就不会取消您的应用程序。它还提供了一种非常完整的方法,可以将插件与除了您给出的合同之外的任何内容相依赖。实际上,您可以对合同适配器进行版本化,以便在升级主应用程序时向旧插件提供向后兼容性。虽然这听起来很棒,但是为了跨域应用程序需要付出沉重的代价。您支付这个价格的速度以及您可以来回发送的类型的灵活性。

MEF更像是依赖注入,具有一些额外的好处,例如可发现性和......(在这一点上留空)。 MEF中不存在MAF具有的隔离程度。它们是两种不同的框架,用于两种不同的东西。

答案 1 :(得分:61)

丹尼尔说的很好。我想补充一下:

如果您观看有关System.Addins的视频,他们显然是在谈论非常大的项目。他谈到管理主机应用程序的团队,管理每个AddIn的另一个团队,以及管理合同和管道的第三个团队。基于此,我认为System.Addins显然适用于更大的应用程序。我正在考虑像SAP这样的ERP系统等应用程序(可能不是那么大,但你明白了)。如果您观看了这些视频,您可以判断使用System.Addins的工作量非常大。如果您有很多公司为您的系统编写第三方加载项,并且您不能以死刑的方式破坏任何这些加载项合同,那么它会很好用。

另一方面,MEF似乎与SharpDevelop的插件方案,Eclipse插件架构或Mono.Addins有更多相似之处。它比System.Addins更容易理解,我相信它更灵活。您失去的是您没有获得与MEF开箱即用的AppDomain隔离或强版本合同。 MEF的优势在于您可以将整个应用程序构建为零件组合,因此您可以为不同的客户提供不同配置的产品,如果客户购买了新功能,您只需将该功能的部件放入其安装目录中并且应用程序看到并运行它。它还有助于测试。您可以实例化要测试的对象并为其所有依赖项提供模拟对象,但当它作为组合应用程序运行时,组合过程会自动将所有实际对象挂钩在一起。

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

答案 2 :(得分:57)

开发并发运了MAF应用程序。我对MAF的看法有点疲惫。

MAF在最坏情况下是“解耦”系统或“松散耦合”系统。 MEF最多是“耦合”系统或“松散耦合”系统。

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

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

  2. 根据购买的组件进行许可。我们可以控制用户的角色和权限加载了哪些AddIn,以及AddIn是否被许可使用。

  3. 快速发展(缩短产品上市时间)。 AddIn开发完全符合Agile方法,开发团队一次开发了一个AddIn,而无需与应用程序的其余部分一起开发集成部分。

  4. 改进了QA(一次只有QA一个组件)。然后,QA可以测试并发布一些功能缺陷。测试用例更容易开发和实现。

  5. 部署(在开发和发布组件时添加组件,它们“正常工作”)。部署只是制作AddIn和安装文件的问题。无需其他考虑因素!

  6. 新组件使用旧组件。早期开发的AddIn继续工作。新的AddIns无缝适合应用程序

答案 3 :(得分:25)

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

MEF通常是纯依赖注入方案中的最佳选择,其中提供最终集成解决方案的个人或团队正在组装所有内容并担保整体完整性,但需要具有不同的关键功能实现。

MAF用于某人/群组正在开发平台或主机的情况,其他群组将在事后以不受主机组控制的方式添加功能。在这种情况下,需要更复杂的机制来“保护”主机免受恶意加载项的攻击(或保护加载项彼此)。

第三种类似模式技术是整个ProviderBase方案。这也可以替换功能,但其目标实际上是主机/应用程序绝对需要功能的情况,并且需要通过配置指定不同的实现。

答案 4 :(得分:17)

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

除了其他答案所提出的观点之外,听起来好像MEF和MAF之间的关键区别之一是Managed Extensibility Framework允许一个可组合部分依赖另一个。例如,它会让插件依赖于另一个插件。

Managed Extensibility Framework也没有真正区分主机和加载项,就像System.AddIn那样。就MEF而言,它们都只是可组合的部分。

答案 5 :(得分:8)

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

MEF: Simple calculator example using MEF parts
M anaged E 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: Simple calculator with V1 and V2 version MAF plugins
M anaged A ddin F ramework)

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

MEF和MAF都包含在.NET Framework 4.x中。如果比较这两个例子,你会发现MAF插件与MEF框架相比复杂得多 - 所以你需要仔细考虑何时使用这些框架。

答案 6 :(得分:2)

MAF和MEF都可以使用AppDomains,并且两者都可以在运行时加载/卸载dll。然而,我发现的差异是:MAF AddIns是解耦的,MEF组件松散耦合; MAF"激活" (新实例),而MEF默认生成实例。

使用MEF,您可以使用Generics为任何合同制作GenericHost。这意味着MEF加载/卸载和组件管理可以在一个公共库中并一般使用。