托管扩展框架(MEF)和托管加载项框架(MAF,又名System.AddIn)似乎完成了非常相似的任务。根据这个堆栈溢出问题,MEF是否可以替代System.Addin?,您甚至可以同时使用两者。
您何时选择使用一个与另一个?在什么情况下您会选择同时使用两者?
托管扩展框架(MEF)和托管加载项框架(MAF,又名System.AddIn)似乎完成了非常相似的任务。根据这个堆栈溢出问题,MEF是否可以替代System.Addin?,您甚至可以同时使用两者。
您何时选择使用一个与另一个?在什么情况下您会选择同时使用两者?
Answers:
我一直在评估这些选项,这就是我得出的结论。
MAF是真正的插件框架。您可以完全分离您的插件,甚至可以在单独的应用程序域中运行它们,这样,如果某个插件崩溃,它就不会关闭您的应用程序。它还提供了一种非常完整的方法来使附加组件脱离耦合,这取决于您提供的合同以外的任何内容。实际上,您可以对合同适配器进行版本控制,以在升级主应用程序时向后兼容旧插件。虽然这听起来不错,但要跨越应用程序域,您必须付出沉重的代价。您为此付出的代价是速度和来回发送类型的灵活性。
MEF更像是依赖项注入,它具有一些其他好处,例如可发现性和...(为此空白)。MAF具有的隔离度在MEF中不存在。它们是针对两个不同事物的两个不同框架。
Danielg所说的很好。我会补充:
如果您观看有关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好处是:
在应用程序运行时安装新组件或更新现有组件。可以在应用程序运行时更新AddIn,并且更新对用户无缝显示。您必须为此拥有AppDomains。
根据购买的组件进行许可。我们可以通过用户的角色和权限来控制加载哪个AddIn,以及该AddIn是否已获得使用许可。
快速发展(更快的上市时间)。AddIn开发非常适合敏捷方法,开发团队一次开发了一个AddIn,而不必同时开发与应用程序其余部分的集成。
改进的质量检查(一次仅对一个组件进行质量检查)。然后,质量检查人员可以针对单个功能进行测试并发布缺陷。测试用例更易于开发和实施。
部署(在开发和发布组件时添加组件,它们“可以正常工作”)。部署仅是制作一个插件并安装文件的问题。无需其他考虑!
新组件与旧组件一起使用。早期开发的AddIn可以继续使用。新的插件可以无缝地集成到应用程序中
在我看来,这两种技术实际上针对的是非常不同的用例。
MEF通常是在纯粹的依赖注入方案中最好的方案,在这种方案中,提供最终集成解决方案的人员或团队正在组装所有东西并保证整体完整性,但是需要采用关键功能的不同实现。
MAF适用于某个人/组正在开发平台或主机,而其他组在事后且以不受主机组控制的方式添加功能的场景。在这种情况下,需要更复杂的机制来“保护”主机免受恶意加载项的影响(或防止加载项彼此之间的冲突)。
第三种相似模式技术是整个ProviderBase方案。这也使替换功能成为可能,但其目标实际上是主机/应用程序绝对需要功能并且实际上需要通过config指定不同实现的场景。
我刚刚发现这篇冗长的文章同时讨论了MAF和MEF。 http://emcpadden.wordpress.com/2008/12/07/managed-extensibility-framework-and-others/
除了其他答案提出的要点外,MEF和MAF之间的主要区别之一似乎是托管可扩展性框架将允许一个可组合部分依赖另一个。例如,它将使一个插件依赖于另一个插件。
托管扩展框架也没有像System.AddIn那样真正区分主机和外接程序。就MEF而言,它们都是可组合的部分。
我认为,发现差异的最佳方法是一些动手代码。我发现了两个MSDN演练,两个演练都有一个计算器示例,因此您可以轻松比较它们的实现:
MEF: 使用简单的计算器例子MEF部分
(中号 anaged ê xtensibility ˚F ramework)
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插件
(中号 anaged 一个 ddin ˚F ramework)
Pipeline AddIns CalcV1 CalcV2 AddInSideAdapters AddInViews Contracts HostSideAdapters
.NET Framework 4.x中包含MEF和MAF。如果比较这两个示例,您会注意到MAF插件比MEF框架复杂得多-因此您需要仔细考虑何时使用那些框架。