写在前面:下面学习所得多是从自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.示例下载