1、MEF是什麼html
Managed Extensibility Framework (MEF) 是用於建立可擴展的輕量級應用程序的庫。 它讓應用程序開發人員得以發現和使用擴展且無需配置。 它還讓擴展開發人員得以輕鬆地封裝代碼並避免脆弱的緊密依賴性。 MEF 讓擴展不只可在應用程序內重複使用,還能夠跨程序重複使用。git
MEF 經過組合提供了一種隱式發現它們的方法,而不是明確記錄可用組件。 MEF 組件(稱爲一個部件),以聲明方式詳細說明了其依賴項(稱爲導入)及其可提供的功能(稱爲導出)。 當建立一個部分時,MEF 組合引擎利用從其餘部分得到的功能知足其導入須要。github
一句話,MEF就是面向接口編程的應用,接口定義行爲,它把實例化類放到代碼運行的時候,經過容器參數肯定。編程
2、MEF示例測試
在咱們國家,無論你在哪一個銀行辦理銀行卡,只要銀行卡有銀聯標識,那麼你就基本能夠在任意一家銀行取錢、存錢。中國銀聯(China UnionPay)成立於2002年3月,是經國務院贊成,中國人民銀行批准設立的中國銀行卡聯合組織,在境內的銀行必須都支持銀聯。也就是說,中國銀聯定義了一些行爲,例如用戶能夠取錢、存錢,任意一家境內銀行都必須支持銀聯定義的行爲。所以,你在任意一家銀行辦理銀行卡後,就能夠在全部的銀行都進行取錢、存錢等及行爲。下面咱們以此爲例,進行一個簡單的例子:spa
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel.Composition; 4 using System.ComponentModel.Composition.Hosting; 5 using System.Linq; 6 using System.Reflection; 7 using System.Text; 8 using System.Threading.Tasks; 9 10 namespace MEF1 11 { 12 class Operation 13 { 14 static void Main(string[] args) 15 { 16 BlankOperation("CBC",300,100); 17 Console.WriteLine("------------------------------"); 18 BlankOperation("BOC",888,666); 19 Console.ReadKey(); 20 } 21 22 static void BlankOperation(string bankName,int saveMonenyAmout,int withdrawMoneyAmount) 23 { 24 var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 25 CompositionContainer container = new CompositionContainer(catalog); 26 var dev = container.GetExportedValue<IUnionPay>(bankName); 27 dev.SaveMoneny(saveMonenyAmout); 28 dev.WithdrawMoney(withdrawMoneyAmount); 29 } 30 } 31 32 33 interface IUnionPay 34 { 35 /// <summary> 36 /// 存錢 37 /// </summary> 38 /// <param name="amount">存錢金額</param> 39 void SaveMoneny(int amount); 40 41 /// <summary> 42 /// 取錢 43 /// </summary> 44 /// <param name="amount">取錢金額</param> 45 void WithdrawMoney(int amount); 46 47 } 48 49 /// <summary> 50 /// 工商銀行 51 /// </summary> 52 [Export("CBC",typeof(IUnionPay))] 53 class ICBC : IUnionPay 54 { 55 public void SaveMoneny(int amount) 56 { 57 Console.WriteLine($"把錢存入工商銀行,金額爲:{amount}"); 58 } 59 60 public void WithdrawMoney(int amount) 61 { 62 Console.WriteLine($"從工商銀行取錢,金額爲:{amount}"); 63 } 64 } 65 66 /// <summary> 67 /// 建設銀行 68 /// </summary> 69 [Export("CCB", typeof(IUnionPay))] 70 class CCB : IUnionPay 71 { 72 public void SaveMoneny(int amount) 73 { 74 Console.WriteLine($"把錢存入建設銀行,金額爲:{amount}"); 75 } 76 77 public void WithdrawMoney(int amount) 78 { 79 Console.WriteLine($"從建設銀行取錢,金額爲:{amount}"); 80 } 81 } 82 83 /// <summary> 84 /// 農業銀行 85 /// </summary> 86 [Export("ABC", typeof(IUnionPay))] 87 class ABC : IUnionPay 88 { 89 public void SaveMoneny(int amount) 90 { 91 Console.WriteLine($"把錢存入建設銀行,金額爲:{amount}"); 92 } 93 94 public void WithdrawMoney(int amount) 95 { 96 Console.WriteLine($"從建設銀行取錢,金額爲:{amount}"); 97 } 98 } 99 100 /// <summary> 101 /// 中國銀行 102 /// </summary> 103 [Export("BOC", typeof(IUnionPay))] 104 class BOC : IUnionPay 105 { 106 public void SaveMoneny(int amount) 107 { 108 Console.WriteLine($"把錢存入建設銀行,金額爲:{amount}"); 109 } 110 111 public void WithdrawMoney(int amount) 112 { 113 Console.WriteLine($"從建設銀行取錢,金額爲:{amount}"); 114 } 115 } 116 }
代碼運行後,效果以下:code
3、MEF示例改進htm
那若是咱們再增長一個銀行實現類,例如招商銀行,那麼須要在MEF1解決方案中增長一個 「CMB」類。但若是咱們的程序已經運行了,此時關閉程序,就會影響用戶在四大行也沒法進行取錢和存錢了,那如何在不關閉程序的前提下,還完成招商銀行接入銀聯卡呢?blog
答案是爲每一個銀行實現類建立一個解決方案,而後編譯成dll文件,這樣咱們在支持招商銀行接入銀聯時,只須要把 「CMB.dll」文件放入對應目錄,就能夠即不關閉主程序,還能夠無縫支持招商銀行接入銀聯,方案目錄以下:接口
咱們把實現銀聯的銀行的解決方案的生成目錄保存在目錄 「..\bin\Debug\bank\」,用於測試的解決方案和銀聯接口的解決方案生成目錄保存在目錄 「..\bin\Debug\」,編譯程序,生成文件以下圖:
而後測試解決方案LOC容器加載的目錄也需修改成bank目錄下:
1 using ChinaUnionPay; 2 using System; 3 using System.Collections.Generic; 4 using System.ComponentModel.Composition.Hosting; 5 using System.IO; 6 using System.Linq; 7 using System.Reflection; 8 using System.Text; 9 using System.Threading.Tasks; 10 11 namespace BankOperation 12 { 13 class Program 14 { 15 static void Main(string[] args) 16 { 17 while (true) 18 { 19 Console.Write($"請輸入銀行名稱:"); 20 string name = Console.ReadLine(); 21 BlankOperation(name, 300, 100); 22 Console.WriteLine("----------------------------------"); 23 } 24 } 25 26 static void BlankOperation(string bankName, int saveMonenyAmout, int withdrawMoneyAmount) 27 { 28 AggregateCatalog catelog = new AggregateCatalog(); 29 30 // 添加部件所在文件目錄 31 string path = $"{Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath)}\\bank\\"; 32 catelog.Catalogs.Add(new DirectoryCatalog(path)); 33 34 // 聲明容器 35 CompositionContainer container = new CompositionContainer(catelog); 36 var dev = container.GetExportedValue<IUnionPay>(bankName); 37 38 // 動做調用 39 dev.SaveMoneny(saveMonenyAmout); 40 dev.WithdrawMoney(withdrawMoneyAmount); 41 } 42 } 43 }
此時運行測試程序,運行效果以下:
此時,若在程序運行的時候添加招商銀行,咱們需添加招商銀行的解決方案以下,而後編譯生成:
1 using ChinaUnionPay; 2 using System; 3 using System.Collections.Generic; 4 using System.ComponentModel.Composition; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace CMB 10 { 11 /// <summary> 12 /// 招商銀行 13 /// </summary> 14 [Export("CMB",typeof(IUnionPay))] 15 public class Operation : IUnionPay 16 { 17 public void SaveMoneny(int amount) 18 { 19 Console.WriteLine($"把錢存入招商銀行,金額爲:{amount}"); 20 } 21 22 public void WithdrawMoney(int amount) 23 { 24 Console.WriteLine($"從招商銀行取錢,金額爲:{amount}"); 25 } 26 } 27 }
運行效果以下:
咱們發現,使用MEF模式能夠「高內聚,低耦合」,大大下降了代碼的解耦,每次使一個銀行接入銀行的時候,徹底不影響其餘銀行的正常業務操做。
4、示例代碼地址
代碼地址:https://github.com/Dwayne112401/MEFDemo.git
控制反轉(一)地址:https://www.cnblogs.com/dongweian/p/12511272.html