寫在前面:下面學習所得多是從自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.示例下載