繁体   English   中英

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

[英]Choosing between MEF and MAF (System.AddIn)

托管可扩展性框架(MEF)和托管AddIn框架(MAF,又名System.AddIn)似乎完成了非常类似的任务。 根据这个Stack Overflow问题, MEF是System.Addin的替代品吗? ,你甚至可以同时使用两者。

你什么时候选择使用一个与另一个? 在什么情况下你会选择同时使用它们?

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

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

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

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

如果您观看有关System.Addins的视频,他们显然是在谈论非常大的项目。 他谈到一个团队管理的主机应用程序,另一个团队管理每个加载项和第三管理合同和管道。 基于此,我认为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/07/managed-extensibility-framework-and-others/

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

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

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

MEF: 使用MEF部件的简单计算器示例
M anaged E xtensibility F ramework)

  • 演示如何使用MEF技术构建简单的计算器。 不显示如何加载外部dll。 (但您可以通过使用catalog.Catalogs.Add(new DirectoryCatalog("Plugins", "*.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; } } [Export(typeof(IOperation))] [ExportMetadata("Symbol", '+')] class Add: IOperation { public int Operate(int left, int right) { return left + right; } }

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

MAF: 带有V1和V2版MAF插件的简单计算器
M anaged A ddin F ramework)

  • 演示如何使用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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM