【问题标题】:Choosing between MEF and MAF (System.AddIn)在 MEF 和 MAF 之间进行选择(System.AddIn)
【发布时间】:2009-05-07 14:59:24
【问题描述】:

托管可扩展性框架 (MEF) 和托管插件框架 (MAF,又名 System.AddIn) 似乎完成了非常相似的任务。根据这个 Stack Overflow 问题 Is MEF a replacement for System.Addin?,您甚至可以同时使用两者。

您会在什么时候选择使用其中一种与另一种?在什么情况下你会选择两者一起使用?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 一件小事:请记住,如果您的插件在本机层崩溃,“单独的应用程序域”对您没有帮助,因为您仍然需要工作进程。 MAF 在一定程度上有助于创建它们,但从这种崩溃中动态恢复仍然非常困难(但可能)
    • @Ian:请重读我的评论:) 我已经写了,而且更多:MAF 确实允许这样做,但你必须在崩溃后自己起床。
    • @DanielG >为了跨应用程序域你必须付出沉重的代价
    • @MartinMeeser 跨应用程序域时,您必须序列化所有内容或使用 MarshalByRef 对象。与同一个应用程序域中的对象之间的通信相比,通信要困难得多。
    【解决方案2】:

    Danielg 说的很好。我要补充:

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

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

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

    【讨论】:

    【解决方案3】:

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

    MAF 在最坏的情况下是一个“去耦合”系统或“松耦合”系统。 MEF 充其量是“耦合”系统或“松耦合”系统。

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

    1. 在应用程序运行时安装新组件或更新现有组件。插件可以在应用程序运行时更新,并且更新会无缝地呈现给用户。为此,您必须拥有 AppDomain。

    2. 基于购买的组件的许可。我们可以控制用户的角色和权限加载了哪些 AddIn,以及该 AddIn 是否获得使用许可。

    3. 快速开发(更快的上市时间)。插件开发与敏捷方法完美契合,开发团队一次开发一个插件,而无需与应用程序的其余部分一起开发集成部分。

    4. 改进的 QA(一次仅 QA 一个组件)。然后,QA 可以针对单个功能测试和发布缺陷。测试用例更容易开发和实施。

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

    6. 新组件与旧组件一起使用。早期开发的插件继续工作。新插件无缝融入应用程序

    【讨论】:

    • 我已经在 .NET 4 上使用 MEF 完成了上述所有操作,我认为它比 MAF 更简单......
    • @Jim:您可以在运行时卸载现有的 MEF 加载项吗?据我所知,加载项程序集一旦加载就无法卸载,因为它位于同一个 AppDomain 中。
    • @Scott - +1(我可以提供多个吗?)此处未列出的另一个好处:您可以使用 MAF 沙箱化插件的安全权限,而 MEF 中的组件使用的安全权限将与正在运行的应用程序共享相同的权限。
    • @ScottWhitlock:您暗示不可能将 MEF 与多个 AppDomain 一起使用,这是不正确的。
    【解决方案4】:

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

    MEF 通常最适合纯依赖注入场景,其中交付最终集成解决方案的个人或团队正在组装所有内容并保证整体完整性,但需要对关键功能进行不同的实现。

    MAF 适用于某人/组正在开发平台或主机,而其他组将在事后以不受主机组控制的方式添加功能的情况。在这种情况下,需要更精细的机制来“保护”主机免受恶意插件的侵害(或相互保护插件)。

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

    【讨论】:

      【解决方案5】:

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

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

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

      【讨论】:

        【解决方案6】:

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

        MEF: Simple calculator example using MEF parts
        M管理的E可扩展性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: Simple calculator with V1 and V2 version MAF plugins
        M管理Addin F框架)

        • 展示了如何使用 V1 插件构建计算器,然后如何在保持向后兼容性的同时转移到 V2 插件(注意:您可以找到该插件的 V2 版本@ 987654323@,原文章链接失效)
        • MAF 强制一个特定的目录结构,,它需要大量的样板代码才能使其工作,因此我不推荐它用于小型项目。 示例:
          Pipeline
            AddIns
              CalcV1
              CalcV2
            AddInSideAdapters
            AddInViews
            Contracts
            HostSideAdapters
          

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

        【讨论】:

          【解决方案7】:

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

          借助 MEF,您可以使用泛型为任何合约创建 GenericHost。这意味着 MEF 加载/卸载和组件管理可以在一个通用库中并通用。

          【讨论】:

            猜你喜欢
            • 2010-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-29
            • 2010-12-06
            • 2012-04-13
            • 2013-06-06
            相关资源
            最近更新 更多