.Net插件编程模型:MEF和MAF
MEF和MAF都是C#下的插件编程框架,我们通过它们只需简单的配置下源代码就能轻松的实现插件编程概念,设计出可扩展的程序。这真是件美妙的事情!
MEF(Managed Extensibility Framework)
MEF的工作原理大概是这样的:首先定义一个接口,用这个接口来约束插件需要具备的职责;然后在实现接口的程序方法上面添加反射标记“[Export()]”将实现的内容导出;最后在接口的调用程序中通过属性将插件加载进来。我们还是用代码来描述吧:
1. 定义一个接口:
2. 实现定义的接口(部分一)
实现定义的接口(部分二)
分析:
标记“[Export(typeof(ICalculator))]”声明表达的意思是:这个类可以编译为插件,并能放入插件容器“ICalculator”中。这里需要注意的是:部分一和部分二的代码分布在不同的程序集中。导出的插件不一定必须是以类的形式,也可以是方法。
通过导出方法来生成插件:
插件的调用者:
分析:
标记“[ImportMany(typeof(ICalculator))]”,该声明表达的意图是:将所有声明了标记“[Export(typeof(ICalculator))]”的程序集加载进容器。这里“[ImportMany]和”[Import]”的区别就是:前者的容器可以存放多个插件,而后者只能存放一个。
光声明“[Import()]”和”[Export()]”标记是不行的,还必须通过下面的代码将这两个标记的功能联合起来:
执行结果
Name:+,number operands:2
Name:-,number operands:2
Name:*,number operands:2
Name:/,number operands:2
Operation?+
operand 1?
1
operand 2?
1
calling calculator
result:2
Operation?exit
you are dead!!!
|
MAF(Managed Addin Framework)
MAF也是.Net为我们提供的一个“插件编程”解决方案。它比MEF复杂,需要配置很多元素。但它也有些优点:1.宿主程序和插件程序可以进行隔离,以此降低运行插件所带来的风险;2。MAF的设计是基于7个程序集组成的管道,这些管道部分可以单独更换,这些管道的详细情况见下图。

图1
使用MAF是需要有些细节需要注意:组成管道的7个程序集在系统中的保存路径有格式要求,并且没个保存它的文件夹内只运行同时出现一个程序集。具体情况如下图所示:

图2

图3

图4

图5
下面我们来看一个小Demo吧,这个demo一共有7个项目,它们分别对应图1描述的管道中的7个部分。具体情况见下图。

图6
插件:Addin_1,Addin_2
插件视图:AddinSideView
插件适配器:AddinSideAdapter
协定:IContract
宿主视图:HostSideView
宿主适配器:HostSideAdapter
宿主程序:Host
|
程序代码
Addin_1
Addin_2
AddinSideView
AddinSideAdapter
IContract
HostSideView
HostSideAdapter
Host
分析
在上面的7个程序集,起解耦作用的关键还是2个适配器类。调用程序不直接调用协定,而是通过通过调用这2个适配器来间接调用协定。
小结
MEF和MAF为我们实现“插件编程”提供了2中选择,它们设计的出发点也是完全不同的。在使用它们的时候还是需要更加具体需求来权衡使用。
分享到:
相关推荐
虽然MEF和MAF(Managed Add-in Framework)都是.NET中的插件框架,但它们的设计理念和应用场景有所不同: - **MEF**:更侧重于轻量级的插件系统,适用于大部分需要动态扩展的应用场景,如桌面应用、Web应用等。MEF...
19.2.3 绑定到ADO.NET对象 514 19.2.4 绑定到LINQ表达式 515 19.3 提高大列表的性能 518 19.3.1 虚拟化 518 19.3.2 项容器再循环 519 19.3.3 缓存长度 519 19.3.4 延迟滚动 520 19.4 验证 521 19.4.1 在数据对象中...
19.2.3 绑定到ADO.NET对象 514 19.2.4 绑定到LINQ表达式 515 19.3 提高大列表的性能 518 19.3.1 虚拟化 518 19.3.2 项容器再循环 519 19.3.3 缓存长度 519 19.3.4 延迟滚动 520 19.4 验证 521 19.4.1 在数据对象中...