實戰MEF(4):搜索範圍

在前面的文章中,幾乎每一個示例咱們都會接觸到擴展類的搜索位置,咱們也不妨想一下,既然是自動擴展,它確定會有一個或者多人可供查找的位置,否則MEF框架怎麼知道哪裏有擴展組件呢數據庫

就像咱們用導航系統去查找某個地方的全部旅店同樣,正由於在該地的旅店已在數據庫中註冊了相關信息,咱們的導航系統才能查找到它,若是某家旅店沒有嚮導航數據庫提供任何數據,那很顯然導航系統是沒法識別到它的詳細地址的。框架

MEF對擴展組件的查找範圍一般有三個:函數

  1. AssemblyCatalog:從某個程序集中查找。
  2. ApplicationCatalog:在應用程序所在的目錄下查找。
  3. DirectoryCatalog:在某個目錄下查找,如D:\\Libs。

若是你還嫌不夠的話,能夠用AggregateCatalog來設置多個查找範圍。佈局

下面咱們來逐個嘗試一下。測試

  1. AssemblyCatalog

基於某個程序集的範圍查找,最常乾的是在當前程序集內查找,固然也能夠在其餘程序集中查找。只要能獲得一個Assembly對象就能夠在其中查找,你們都那麼聰明,我相信你們能理解的。spa

下面是一個典型的作法,例子是在當前程序集中查找擴展部件的。3d

首先,咱們定義一個用於規範擴展部件行爲的接口。orm

而後,寫兩個類來實現上面的接口,並將它們導出。對象

在應用程序類中,用一個公共字段把它們所有導入。blog

最後,在Main中進行組裝並測試調用。

最終,程序運行結果以下圖所示。

 

2、DirectoryCatalog

這一個咱們可能有些陌生,由於在前面文章的示例中,咱們並無使用過該類,可是,不要由於陌生而懼怕,天有多高,你的膽子就應該有多大,陌生的東西不少時候是不復雜的,就好像咱們與陌生人對話有時候反而比與熟人對話更自在。

    DirectoryCatalog類能夠指定一個目錄,讓MEF在這個目錄下面尋找擴展組件,若是須要更細緻的查找,能夠在DirectoryCatalog類的構造函數中指定一個搜索字符串,這個字符串與咱們平時搜索文件同樣,例如"ext_*",這代表只要以ext_開頭的類庫文件都在查找範圍內。

這一次,咱們用一個WinForm應用程序來作例子,在窗體中咱們拖放幾個控件,詳見下圖。

控件佈局隨意,我一貫主張個性化佈局的,主要如下幾個重要的控件得介紹一下:

名爲txtDirec的TextBox用來顯示選擇的目錄;名爲cmbClass的ComboBox控件用來顯示MEF發現的擴展類的列表,名爲txtResult的TextBox顯示擴展類的調用結果。

下面說一下本例的大概思路,咱們先把擴展的類庫全放到一個任意文件夾下,而後在應用程序窗口上選擇該目錄後,讓MEF框架在該目錄下發現全部擴展類型並顯示在ComboBox中。接着咱們從ComboBox中選擇一個類來調用,並查看調用結果。

  1. 咱們先建一個公共類庫,這個類庫在主應用程序和全部擴展類庫都會引用,由於咱們會在其中定義用於規範組件行爲的"憲法"(接口)。該類庫暫名爲CommonLib,代碼以下,很簡單,不超過10行。

這個接口只有一個方法SaySomething,待會咱們分別用幾個類來實現它,每一個類都獨立寫到一個類庫中。

  1. 新項一個類庫項目,名爲ExtLibA,代碼以下:

一樣道理,再建兩個類庫項目,分別是ExtLibB和ExtLibC。

  1. 分別生成這三個dll,還要包含一個CommonLib.dll,由於三個擴展庫都引用了它。而後把這幾個dll分別放到一個文件夾中,大體以下圖所示。

  1. 回到WinForm項目,在窗體類中聲明一個字段,公有或私有都無所謂,用於導入類型。

  1. 處理按鈕事件,瀏覽目錄,並從指定目錄中尋找擴展部件,而且顯示在ComboBox中。

  1. 處理按鈕事件,調用ComoBox中選定的擴展類型。

而後,咱們能夠看看下面的執行結果。

 

3、AggregateCatalog

有一天,我不當心把新的擴展類ExtLibD寫到了WinForm項目中了,就像這樣:

而後我想,若是能保留前面的三個擴展類的同時,也自動識別我寫到WinForm項目中的擴展類,那該多好啊。不怕,.NET的強大隻有你想不到,沒有它作不到的。這時候我把目光投向AggregateCatalog類,利用它能夠將多個搜索範圍合併,咱們剛纔的三個擴展是經過在一個文件夾中搜索的,而第四個擴展是寫到WinForm項目中的,還記得前文中咱們說過AssemblyCatalog類,它能夠在某個程序集中尋找擴展類,因此第四個擴展類咱們能夠在WinForm項目所在的程序集中查找。

也就是說,咱們把AssemblyCatalog範圍和DirectoryCatalog範圍進行組合。因此,把前面button1_Click的代碼改一下,變成如下這個樣子:

用AggregateCatalog來把DirectoryCatalog和AssemblyCatalog合併起來,再傳給CompositionContainer的構造函數,這樣就能實現查找範圍的組合了。

好,如今運行一下,看看第四個擴展是否是自動被發現了?

Good,預期的效果達到了,是否是很高興呢,喝杯咖啡得意一下吧。

 

不知道你們看了我這幾篇有關MEF的吹牛散文以後,會不會感嘆MEF的神奇呢?無論你們會把MEF用在哪些地方,只要記住兩個原則:

  1. 在須要某項技術時就該當機立斷,不然反受其亂。
  2. 技術運用講求靈活,無招勝有招,就像李小龍的"李三腳"同樣,切忌濫用。

好了,說了這麼多,我也口渴了,先喝杯橙汗解解渴,再見。

相關文章
相關標籤/搜索