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

您什么时候会选择使用一个或多个?另一个?什么情况下您会选择同时使用两者?

有帮助吗?

解决方案

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

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

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

其他提示

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

如果您观看有关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中,人们已经开始使用它构建大量应用程序(包括我自己)。我认为这可以告诉你一些关于这两个框架的内容。

开发并发运了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无缝适合应用程序

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

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

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

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

我刚刚发现这篇冗长的文章讨论了MAF和MEF。 http://emcpadden.wordpress.com/2008/ 12月7日/管理的延伸性的框架和 - 其他/

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

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

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

MEF: 简单的计算器示例使用 MEF零件
(中号被管理的 可扩展性 F框架)

  • 展示如何使用 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 插件
(中号被管理的 AF框架)

  • 展示如何使用 V1 插件构建计算器,然后如何在保持向后兼容性的同时转移到 V2 插件(笔记: 你可以找到该插件的V2版本 这里, ,原文章中的链接已损坏)
  • MAF 强制执行 一个具体的 目录结构, 并且它需要大量的样板代码才能使其工作,因此我不推荐将其用于小型项目。例子:
    Pipeline
      AddIns
        CalcV1
        CalcV2
      AddInSideAdapters
      AddInViews
      Contracts
      HostSideAdapters
    

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top