MEF(Managed Extensibility Framework),所在命名空间是System.ComponentModel.Composition.dll。简单来说,MEF是将符合约定(一般是实现接口)的组件的Parts(类、方法和属性可看作是Part)标记为Export特性,再把这些组件放到与可执行程序同目录的Extensions文件夹中,最后通过把Part标记为Import来引用这些组件,从而为我们创建可扩展组件提供了方便。
● HelloMEF.Lib,类库,包含了一个接口IPlay,即约定
● HelloMEF.BackPlay,类库,包含了一个实现IPlay接口的类Back.cs
● HelloMEF.FowardPlay, 类库,包含一个实现IPlay接口的类Foward.cs
● Portal,控制台应用程序
□ 可扩展的前提是满足约定,即接口
namespace HelloMEF.Lib
{
public interface IPlay
{
string PlaySoccer(string name, string position);
}
}
□ HelloMEF.BackPlay类库中的Back.cs实现IPlay接口
→引用HelloMEF.Lib组件
→引用System.ComponentModel.Composition组件
using System.ComponentModel.Composition;
using HelloMEF.Lib;
namespace HelloMEF.BackPlay
{
[Export(typeof(IPlay))]
public class Back : IPlay
{
public string PlaySoccer(string name, string position)
{
return string.Format("我是{0},司职{1},我的主要任务是防守和传球~~", name, position);
}
}
}
□ HelloMEF.FowardPlay类库中的Foward.cs实现IPlay接口
→引用HelloMEF.Lib组件
→引用System.ComponentModel.Composition组件
using System.ComponentModel.Composition;
using HelloMEF.Lib;
namespace HelloMEF.FowardPlay
{
[Export(typeof(IPlay))]
public class Forward : IPlay
{
public string PlaySoccer(string name, string position)
{
return string.Format("我是{0},司职{1},我的主要任务是传球和射门~~", name, position);
}
}
}
□ 控制台程序
→引用HelloMEF.Lib组件
→引用System.ComponentModel.Composition组件
→在可执行文件所在目录,即输出路径下,创建Extensions文件夹
假设,满足约定的一个或多个组件已经方在Extensions文件夹中了,还需要做的大致包括:
→把所有的组件放在Catalog中
→放到CompositionContainer容器中
→在CompositionContainer容器中组合组件
→以Import标记,注入到某个Part上,比如属性上,由程序来决定使用全部或某些组件
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using HelloMEF.Lib;
namespace Portal
{
class Program
{
[ImportMany(typeof(IPlay))]
public IPlay[] Plays { get; set; }
static void Main(string[] args)
{
Program p = new Program();
p.ShowTeam();
Console.ReadKey();
}
public void ShowTeam()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(@".\Extensions"));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
string name = "";
string position = "";
while (true)
{
Console.WriteLine("输入球员名称");
name = Console.ReadLine();
Console.WriteLine("输入球员位置");
position = Console.ReadLine();
foreach (IPlay play in Plays)
{
Console.WriteLine(play.PlaySoccer(name, position));
}
}
}
}
}
Extensions文件夹只有HelloMEF.FowardPlay.dll,效果如下:
Extensions文件夹中包含HelloMEF.FowardPlay.dll和HelloMEF.BackPlay.dll,效果如下: