前言 前面講解了MEF的引用方法,介面的導入導出,類屬性的導入導出和集合的導出用法其實大家可以看到基本上大同小異的。 MEF的延遲載入 我們知道當裝配一個組件的時候,當前組件裡面的所有的Import的變數都自動去找到對應的Export而執行了實例化,有些時候出於程式效率的考慮,不需要立即實例化對象, ...
前言
前面講解了MEF的引用方法,介面的導入導出,類屬性的導入導出和集合的導出用法其實大家可以看到基本上大同小異的。
MEF的延遲載入
我們知道當裝配一個組件的時候,當前組件裡面的所有的Import的變數都自動去找到對應的Export而執行了實例化,有些時候出於程式效率的考慮,不需要立即實例化對象,而是在使用的時候才對它進行實例化。MEF裡面也有這種延遲載入的機制。
class Program2 { [Import("chinese_hello")] public Person oPerson { set; get; } [Import("american_hello")] public Lazy<Person> oPerson2 { set; get; } static void Main(string[] args) { var oProgram = new Program2(); oProgram.MyComposePart(); var strRes = oProgram.oPerson.SayHello("李磊"); var strRes2 = oProgram.oPerson2.Value.SayHello("Lilei"); Console.WriteLine(strRes); Console.Read(); } void MyComposePart() { var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); //將部件(part)和宿主程式添加到組合容器 container.ComposeParts(this); } } public interface Person { string SayHello(string name); } [Export("chinese_hello", typeof(Person))] public class Chinese : Person { public string SayHello(string name) { return "你好:" + name ; } } [Export("american_hello", typeof(Person))] public class American : Person { public string SayHello(string name) { return "Hello:" + name ; } }
oPerson對象已經實例化了,而oPerson2.Value對象沒有實例化,當程式執行var strRes2 = oProgram.oPerson2.Value.SayHello("Lilei")這一句的時候,oPerson2.Value對象才進行實例化。這種需要在某些對程式性能有特殊要求的情況下麵有一定的作用。
講到這裡,我們再來看前面關於理解MEF的兩個關鍵點:
(1)可擴展的庫:由於MEF允許通過Import的方式直接導入對象、屬性、方法等,試想,有人開發了一個組件,他們事先定義好了一系列的導出(Export),我們只需要將它的組件引進來,使用Import的方式按照他們Export的約定導入對象即可,不用做其他複雜的配置。
(2)能更好的實現“松耦合”:比如我們項目按照面向介面編程的方式這樣分層:UI層、BLL介面層、BLL實現層......UI層只需要引用BLL介面層即可,我們在BLL實現層裡面定義好Export的導出規則,然後再UI層裡面使用Import導入BLL實現層的對象即可,這樣UI層就不需要添加BLL實現層的引用。減少了dll之間的依賴。
MEF系列一共寫了四篇文章,在前面我們都用是ComposePart()方法進行的IOC(一種思想)的組合部件,而在實際項目中是肯定不能這麼寫的原因就不用我多說了吧,給大家推薦一種方法吧MEF註冊部件的類做一個封裝然後寫在Global文件中。Global文件是幹啥的大家就自行百度下哈。
以上就是MEF的一些基礎用法。當然在實際使用中可能不會這麼簡單,但是再複雜的用法都是在這些簡單基礎上面擴展起來的。後面還有兩篇會繼續分享MEF在項目設計層面的用法以及帶來的好處。歡迎各位拍磚斧正~~