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

管理扩展框架(MEF)和管理插件框架(MAF,又名系统)。AddIn)似乎完成了非常相似的任务。根据这个 Stack Overflow 问题 MEF 是系统的替代品吗?,您甚至可以同时使用两个。

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

50664 次浏览

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

MAF 是一个真正的插件框架。您可以完全分离您的插件,甚至在一个单独的应用程序域内运行它们,以便如果一个插件崩溃,它不会关闭您的应用程序。它还提供了一种非常完整的方法,使插件不再依赖于除了您提供的契约之外的任何东西。实际上,您可以对契约适配器进行版本化,以便在升级主应用程序时向后兼容旧的插件。虽然这听起来很棒,但是为了跨应用程序域名,你必须付出沉重的代价。你付出这个代价的速度,也在类型的灵活性,你可以发送来回。

MEF 更像是一种带有额外好处的依赖注入,比如可发现性和... ... (在这一点上一片空白)。MAF 所具有的隔离度在 MEF 中是不存在的。它们是两种不同事物的两种不同框架。

丹尼尔说的很好,我想补充一句:

如果你看了关于 System 的视频。外接程序,他们显然是在谈论非常大的项目。他谈到了管理主机应用程序的一个 团队,管理每个 AddIn 的另一个 团队,以及管理合同和管道的第三个 团队。基于此,我认为系统。Addins 显然适用于较大的应用程序。我在考虑像 SAP 这样的 ERP 系统应用程序(可能没有那么大,但你明白我的意思)。如果你看了这些视频,你就可以知道使用 System 的工作量。Addins 非常大。如果有很多公司为你的系统编写第三方插件,而且你不能违反任何一个这样的插件合同,否则就会被处以死刑,那么它将会很好地工作。

另一方面,MEF 似乎与 SharpDevelopment 的插件方案—— Eclipse 插件架构或 Mono ——有更多的相似之处。阿丁斯。它比 System 更容易理解。Addins 和我相信它更加灵活。你所失去的是,你不能得到 AppDomain 隔离或强版本控制协议与 MEF 开箱即用。MEF 的优势在于,你可以将整个应用程序结构化为一个组成部分,这样你就可以为不同的客户提供不同配置的产品,如果客户购买了一个新功能,你只需将该功能的部分放入他们的安装目录,应用程序就可以看到并运行它。它还有助于测试。您可以实例化要测试的对象,并向其提供所有依赖项的模拟对象,但是当它作为组合应用程序运行时,组合过程会自动将所有实际对象连接在一起。

我想提到的最重要的一点是,即使系统。Addins 已经在框架中了,我没有看到很多人使用它的证据,但是 MEF 只是坐在 CodePlex 上,应该包含在其中。NET 4,人们已经开始用它构建许多应用程序(包括我自己)。我认为这说明了这两个框架的一些问题。

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

在纯依赖注入的情况下,MEF 通常是最好的,在这种情况下,提供最终集成解决方案的个人或团队组装所有东西并保证整体完整性,但需要对关键能力进行不同的实现。

MAF 是一种场景,其中某人/组正在开发一个平台或主机,其他组将在事后以一种不受主机组控制的方式添加功能。在这种情况下,需要更复杂的机制来“保护”主机不受流氓外接程序的侵害(或者相互保护外接程序)。

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

我刚找到这篇讨论 MAF 和 MEF 的长文。 Http://emcpadden.wordpress.com/2008/12/07/managed-extensibility-framework-and-others/

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

托管扩展性框架实际上也没有像系统那样区分主机和外接程序。AddIn 有。就 MEF 而言,它们都只是可组合的部件。

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

MAF 最多是一个“解耦”系统或“松耦合”系统。 MEF 充其量是“耦合”系统或“松耦合”系统。

我们通过使用 MAF 实现的 MAF 效益如下:

  1. 在应用程序运行时安装新组件或更新现有组件。AddIn 可以在应用程序运行时进行更新,并且更新可以无缝地显示给用户。你必须拥有 AppDomains 才能做到这一点。

  2. 基于购买组件的许可证。我们可以控制哪个 AddIn 由用户的角色和权限加载,以及 AddIn 是否被授权使用。

  3. 快速开发(更快的上市时间)。AddIn 开发完全符合敏捷方法,开发团队一次开发一个 AddIn,而不必与应用程序的其他部分一起开发集成部分。

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

  5. 部署(在开发和发布组件时添加这些组件,它们“只是工作”)。部署只是创建一个 AddIn 并安装文件的问题。没有其他的考虑是必要的!

  6. 新的部件和旧的部件一起工作。早期开发的 AddIn 一直在工作。新的 AddIns 无缝地适合应用程序

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

MEF: < a href = “ https://msdn.microsoft.com/en-us/library/dd460648(v = vs. 110) .aspx”rel = “ noReferrer”> 使用 < strong > MEF 部件的简单计算器示例
(Managed Extenability FFramework)

  • 演示如何使用 MEF 技术构建一个简单的计算器。没有显示如何加载外部 dls。(但是您可以简单地通过使用 catalog.Catalogs.Add(new DirectoryCatalog("Plugins", "*.dll")); 而不是使用 < code > Catalogs.Catalogs.Add (new AssemblyCatalog (typeof (Program) . Assembly) ; 并提取 计算器代码和分离 DLL 项目的合同)
  • MEF 没有需要有一个特定的目录结构,它简单易用,即使对于小型项目也是如此。它的 与属性一起工作,声明什么是导出,这是很容易阅读和理解。 例子: [出口(类型(操作)]] [ ExportMetadata (“符号”,’+’)] 类 Add: IOperation { Public int Operate (int left,int right) { 返回左 + 右; } }

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

MAF: < a href = “ https://msdn.microsoft.com/en-us/library/bb788290(v = vs. 110) .aspx”rel = “ noReferrer”> 简单的 V1和 V2版本计算器 < strong > MAF 插件
(M管理的 Addin F框架)

  • 演示如何使用 V1插件构建计算器,然后如何在保持向后兼容性的同时转移到 V2插件(注:你可以找到插件 给你的 V2版本,原文中的链接已经断开)
  • MAF 强制执行是一个特定的 目录结构,,它需要大量的样板代码来使其工作,因此我不推荐小型项目使用它。 例如:
    Pipeline
    AddIns
    CalcV1
    CalcV2
    AddInSideAdapters
    AddInViews
    Contracts
    HostSideAdapters
    

MEF 和 MAF 都包括在。NET Framework 4.x.如果您比较这两个例子,您会注意到 MAF 插件比 MEF 框架复杂得多——因此您需要仔细考虑何时使用这些框架中的哪一个。

MAF 和 MEF 都可以使用 AppDomain,并且都可以在运行时加载/卸载 dll。然而,我发现的不同之处是: MAF AddIns 是解耦的,MEF 组件是松耦合的; MAF“激活”(新实例) ,而 MEF 默认创建实例。

使用 MEF,您可以使用泛型为任何契约制作泛型主机。这意味着 MEF 加载/卸载和组件管理可以放在一个通用库中并通用使用。