实战MEF(1)一种不错的扩展方式2014-03-20在过去,我们完成一套应用程序后,如果后面对其功能进行了扩展或修整,往往需要重新编译代码生 成新的应用程序,然后再覆盖原来的程序。这样的扩展方式对于较小的或者不经常扩展和更新的应用程 序来说是可以接受的,而对于像ERP系统那样复杂而且常常需要扩展的应用程序,这种扩展方法就不够方 便,因为每次都要修改源代码或重新引用组件。尤其是组件(许多dll),如果每编写一个新组 件又要在主项目中引用一次,显然主项目就不得不经常重新生成。要是能有一种机制,可以在主项目应 用程序不作任何修改就可以自动识别并扩展组件,就会很便捷,我们每次扩展只需要更新或者添加某些 dll文件即可。MEF正是为了解决上述问题而诞生。MEF全称Managed Extensibility Framework, 至于如何翻译不重要,你喜欢怎么个译法都无所谓,我们只要明白它用来干啥就好了。宽泛的理 论似乎作用不明显,我们还是先来弄一个简单的例子。现在假设我在开发一个应用程序,首先我要为一 些组件以及将来可以要扩展的组件定义公共接口(或者说是协定,大家是否记得在WCF中也是这样,先定 义一些公共的服务协定,然后视具体情况对这些协定进行扩展),然后我可以按照不同的情形去实现这 些接口,这也是我们常说的,接口可以起到规范作用,有了规范,正是为后期扩展打下可行性基础。例子的主项目是一个控制台应用程序,我们先在解决方案中添加一个类库项目,为了简单演示, 我定义了以下接口:
public interface IExtBase{ void DoTask(); string TaskName { get; }}
这个IExtBase接口就作为我们要扩展的组件的公共协定,不管我以后怎么扩展,哪怕我要添 加100000个组件,这些组件都要实现IExtBase接口。这里我做了两个扩展作为例子,为了表明 MEF框架能自动发现组件,我把两个实现IExtBase接口的类写到另外一个类库项目中——TaskToa.dll。
[Export("task1", typeof(CommExtBase.IExtBase))] public class Task_1 : CommExtBase.IExtBase{ public void DoTask(){ Console.WriteLine("任务1执行。");}public string TaskName{ get{ return "任务1";}}} [Export("task2", typeof(CommExtBase.IExtBase))] public class Task_2 : CommExtBase.IExtBase{ public void DoTask(){ Console.WriteLine("任务2执行。");}public string TaskName{ get { return "任务2"; }}}