一 简介
MEF全称为:ManagedExtensibility Framwork, 是.NET的一个插件框架;编写完一个应用程序,可以通过插件的方式来扩展。
二 MEF的体系结构
有关介绍MEF体系结构部分,个人感觉C#高级编程一书中描述的最好。MEF通过容器与部件构建的,如图所示。容器在类别中查找部件,类别则在程序集或者目录中查找部件,容器则把入口连接到出口,寄宿应用程序则在容器出口调用部件。
三 一个简单的MEF程序
为了是宿主程序与插件程序彼此独立,这里需要建立3个程序集。一个为接口程序集,连接宿主程序与插件程序集,在此程序集中,定义插件程序集中实现的方法、属性等;一个为插件程序集,实现接口程序集中定义的方法、属性等;宿主程序直接引用接口程序集。
这个小程序实现在控制台打印用户信息,接口程序集(IUserInfoContract.dll),插件程序集(SimpleUserInfo.dll)、宿主程序(MEFTest1.exe),此程序是使用特性{import、export}
完后的MEF。
接口程序集:新建类库,定义一个接口IUserInfo (IUserInfo.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plug
{
publicinterfaceIUserInfo
{
string showUserInfo(string name,string UserNumber);
}
}
插件程序集:新建类库,实现IUserInfo定义的showUserInfo方法。
注意:工程调加引用,System.ComponentModel.Composition(SimpleUserInfo.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition;
namespace Plug
{
[Export(typeof(IUserInfo))] //将部件放置在容器出口
publicclassUserInfo:IUserInfo
{
publicstring showUserInfo(string name,string userNumber)
{
return"姓名: " + name + " 工号: " + userNumber;
}
}
}
宿主应用程序:创建控制台应用程序,引用接口程序集(IUserInfoContract.dll)、
System.ComponentModel.Composition
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition;
using Plug;
using System.ComponentModel.Composition.Hosting;
namespace MEFTest1
{
classProgram
{
[Import]
publicIUserInfo userInfo { get; set; }//入口调用接口
staticvoid Main(string[] args)
{
var p = newProgram();
p.Run();
}
publicvoid Run()
{
var catalog = newDirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory);
var container = newCompositionContainer(catalog);
try
{
container.ComposeParts(this);
}
catch (ChangeRejectedException ex)
{
Console.WriteLine(ex.Message);
return;
}
string info =userInfo.showUserInfo("luna","12345678");
Console.WriteLine(info);
Console.ReadKey();
}
}
}
创建Program实例,是因为 userInfo是Program类中一个实例属性。CompositionContainer是一个插件存储库,这里存储(UserInfo),此容器是由DirectoryCatalog初始化,从SimpleUserInfo.dll内获取插件部件。ComposeParts()方法传递带Import特性的部件及参数
效果图:
MEF框架的好处是,宿主程序直接调用接口程序集,而不是调用插件程序集。当需要修改功能时,直接修改插件程序集,然后替换掉原先的插件dll,无需宿主程序再次编译。