写在前面:下面学习所得多是从自http://www.cnblogs.com/comsokey/p/MEF1.html和http://www.cnblogs.com/yunfeifei/p/3922668.html两位大神的文章里学到的,特别鸣谢!整理下是更大一方面是对自己知识的梳理,用词用句不够准确,见谅,看不懂的可自行参考两位大神的原文。
一.定义和特性
定义:MEF=Managered Extensibility Framework.
特性:减少代码耦合度,利用封装代码轻松搞定工程。
我的理解:利用Export与Import相协作,让系统自动匹配需要。
本文实例在后面有下载,内部各代码都有解释,不懂的可以下载看看。
二.实例说话
1.定义接口
namespace MEFMovie { public interface Data { string Name { get; set; } string Type { get; set; } string TimeOut { get; set; } string GetMovie(); } }
定义interface接口为后面需要继承的类做准备
2.数据类设置
namespace MEFMovie { [Export("HorribleMovie", typeof(Data))] public class HorribleMovie : Data { public string Name { get; set; } public string Type { get; set; } public string TimeOut { get; set; } public string GetMovie() { Name = "11111"; return "HorribleMovie"; } } [Export(typeof(Data))] [ExportMetadata("obj","00000")] public class LoveMovie : Data { [Export(typeof(string))] public string MovieAct01 = "周杰伦"; [Export(typeof(string))] public string MovieAct02 = "周润发"; [Export(typeof(string))] public string MovieAct03 = "周星驰"; public string Name { get; set; } public string Type { get; set; } public string TimeOut { get; set; } public string GetMovie() { return "LoveMovie"; }
} [Export("ComedyMovie", typeof(Data))] [ExportMetadata("obj", "222222")] public class ComedyMovie : Data { public string Name { get; set; } public string Type { get; set; } public string TimeOut { get; set; } public string GetMovie() { return "ComedyMovie"; } } }
在继承时需要把接口相应的属性和方法完整写出来(Name,Type,TimeOut和GetMovie)
Export为导出该继承类的数据,在使用时请先引用
Export格式为[Export("XXX",TypeOf(XX))]
其中"XXX"是契约名,这是为了在继承类很多时,方便寻找需要的类,契约名可以不写,[Export(TypeOf(XX))]。
TypeOf(XX)是指导出类型,XX一般是类继承的接口
上述三个类分别用了三种导出方式:
1.HorribleMovie:[Export("HorribleMovie", typeof(Data))]
2.LoveMovie:[Export(typeof(Data))]
3.ComedyMovie:[Export("ComedyMovie", typeof(Data))]
这是博主在疑问Export的使用格式时做的N多无用测试,有疑问的可以继续试试
3.辅助插件
public interface OtherMate { string obj { get; } }
后面会做解释
4.数据显示
namespace MEFMovie { public class DataManager { public string Act { get; set; }
//对应[Export("HorribleMovie", typeof(Data))]导出内容 [Import("HorribleMovie")] Data HorribleMovieData; //导入多个继承接口Data的类 [ImportMany(typeof(Data))] public IEnumerable<Data> datass { get; set; } [ImportMany(typeof(Data))] public IEnumerable<Lazy<Data, OtherMate>> data { get; set; } //对应导出 [Export("ComedyMovie", typeof(Data))] [Import("ComedyMovie")] Data ComedyMovie { get; set; } //对应所有 [Export(typeof(string))] [ImportMany(typeof(string))] public List<string> MovieActs { get; set; } //程序启动时,做下列动作 public void Open() { //找到所有文件下的dll程序集(只有这样才能找到Datas下的各个数据类) //注意引用:using System.ComponentModel.Composition; //using System.ComponentModel.Composition.Hosting;
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); container.ComposeParts(this); //下面是对数据做出显示,方便辩证程序是否成功 //对导入的string类型数据做遍历 并显示 foreach (var ss in MovieActs) { Act += ss; } //对导入HorribleMovie做辩证 Act += HorribleMovieData.GetMovie();
//对导入的ComedyMovie做辩证 Act += ComedyMovie.GetMovie();
//对接口的属性做辩证 前面赋值"11111" Act += HorribleMovieData.Name; //辅助插件的作用:在这个程序里是对数据做筛选 foreach (var s in data.Where(item => item.Metadata.obj == reds())) { Act += s.Metadata; } } //筛选标准 private string reds() { string s = "00000"; return s; } }
上面各Import是对导出的Export做导入
ImportMany是指导入多个,它后面的TpyeOf可以省略不写,ImportMany即可。
public IEnumerable<Lazy<Data, OtherMate>> data { get; set; } 是用辅助插件做筛选,后续调用item.metadata.obj做比较得出结果。
5.示例下载