代码之家  ›  专栏  ›  技术社区  ›  dthrasher

在MEF和MAF(system.addin)之间进行选择

  •  157
  • dthrasher  · 技术社区  · 16 年前

    托管扩展性框架(mef)和托管加载项框架(maf,aka system.addin)似乎完成了非常相似的任务。根据这个堆栈溢出问题, Is MEF a replacement for System.Addin? 您甚至可以同时使用这两种方法。

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

    7 回复  |  直到 7 年前
        1
  •  126
  •   SwDevMan81    7 年前

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

    MAF是一个真正的插件框架。你可以完全分离你的插件,甚至在一个单独的应用程序域中运行它们,这样如果一个插件崩溃,它就不会破坏你的应用程序。它还提供了一种非常完整的方法,可以将附加组件与所提供的合同以外的任何内容分离开来。实际上,在升级主应用程序时,您可以对合同适配器进行版本化,以向后兼容旧的加载项。虽然这听起来很好,但它带来了一个沉重的代价,你必须支付,以跨应用程序域。您以速度和您可以来回发送的类型的灵活性来支付这个价格。

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

        2
  •  61
  •   Scott Whitlock    16 年前

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

    如果你看有关System.Addins的视频,他们显然在谈论非常大的项目。他说了一个 团队 管理主机应用程序,另一个 团队 管理每个加载项和第三个加载项 团队 管理合同和管道。基于此,我认为System.Addins显然适用于更大的应用程序。我认为像SAP这样的ERP系统应用程序(也许没那么大,但你明白了)。如果你看了这些视频,你就可以知道使用System.Addins的工作量很大。如果有很多公司为您的系统编写第三方加载项,并且您不能在死刑下违反任何加载项合同,这将很好地工作。

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

    我要提到的最重要的一点是,即使System.Addins已经在框架中了,我也看不到很多人使用它的证据,但是MEF只是坐在CodePlex上,据说它包含在.NET 4中,人们已经开始用它构建许多应用程序(包括我自己)。我想这会告诉你关于这两个框架的一些事情。

        3
  •  57
  •   Lance Roberts    12 年前

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

    MAF最坏是一个“非耦合”系统或“松散耦合”系统。 MEF最多是“耦合”系统或“松散耦合”系统。

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

    1. 在应用程序运行时安装新组件或更新现有组件。可以在应用程序运行时更新外接程序,用户可以无缝地看到更新。你必须有AppDomain。

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

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

    4. 改进的质量保证(一次仅质量保证一个组件)。然后,QA可以为一个功能位测试和发布缺陷。测试用例更容易开发和实现。

    5. 部署(在开发和发布组件时添加组件,它们只工作)。部署只是制作一个外接程序和安装文件的问题。无需考虑其他因素!

    6. 新组件与旧组件一起工作。早期开发的addin继续工作。新的外接程序无缝地适合应用程序

        4
  •  25
  •   Raoul    16 年前

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

    在纯依赖注入场景中,提供最终集成解决方案的人员或组正在组装所有内容并保证总体完整性,但需要对关键功能进行不同的实现,MEF通常是最好的。

    MAF是指某人/组正在开发平台或主机,而其他组将在事实发生后以不受主机组控制的方式添加功能的场景。在这个场景中,需要更复杂的机制来“保护”主机不受恶意加载项的影响(或者保护加载项不受其他加载项的影响)。

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

        5
  •  17
  •   dthrasher    16 年前

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

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

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

        6
  •  8
  •   Matt    8 年前

    在我看来,发现差异的最好方法是一些实际操作的代码。我发现了两个msdn演练,都有一个计算器示例,这样您就可以轻松地比较它们的实现:

    MEF: Simple calculator example using MEF parts
    ( 老化的 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
    ( 老化的 敌敌畏 f 游戏工

    • 演示如何使用v1插件构建计算器,然后如何在保持向后兼容性的同时移到v2插件。( 注: 您可以找到插件的v2版本 here ,原始文章中的链接已断开)
    • MAF 强制执行 特定的 目录结构, 它需要很多样板代码才能工作,因此我不推荐它用于小型项目。 例子:
      Pipeline
        AddIns
          CalcV1
          CalcV2
        AddInSideAdapters
        AddInViews
        Contracts
        HostSideAdapters
      

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

        7
  •  2
  •   JeffBramlett Jeff Bramlett    8 年前

    MAF和MEF都可以使用AppDomain,并且都可以在运行时加载/卸载DLL。然而,我发现的区别是:MAF加载项是分离的,MEF组件是松散耦合的;MAF“激活”(新实例),而MEF默认情况下创建实例。

    使用MEF,您可以使用泛型为任何合同生成generichost。这意味着MEF加载/卸载和组件管理可以在一个公共库中,并且可以一般使用。

    推荐文章