程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> 實戰MEF(4)搜索范圍

實戰MEF(4)搜索范圍

編輯:關於C#

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

就像我 們用導航系統去查找某個地方的所有旅店一樣,正因為在該地的旅店已在數據庫中注冊了相關信息,我 們的導航系統才能查找到它,如果某家旅店沒有向導航數據庫提供任何數據,那很顯然導航系統是無法 識別到它的詳細地址的。

MEF對擴展組件的查找范圍通常有三個:

AssemblyCatalog:從某個程序集中查找。

ApplicationCatalog:在應用程序所在的目錄下查找。

DirectoryCatalog:在某個目錄下查找,如D:\\Libs。

如果你還嫌不夠的話,可以用AggregateCatalog來設置多個查找范圍。

下面我們來逐個嘗試 一下。

AssemblyCatalog

基於某個程序集的范圍查找,最常干的是在當前程序集內查找,當然也可以在其他程序集中查找。只 要能得到一個Assembly對象就可以在其中查找,大家都那麼聰明,我相信大家能理解的。

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

首先,我們定義一個用於規范擴展部 件行為的接口。

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

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

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

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

二、 DirectoryCatalog

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

DirectoryCatalog類可以指定一個 目錄,讓MEF在這個目錄下面尋找擴展組件,如果需要更細致的查找,可以在DirectoryCatalog類的構造 函數中指定一個搜索字符串,這個字符串與我們平時搜索文件一樣,例如"ext_*",這表明只 要以ext_開頭的類庫文件都在查找范圍內。

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

控件布局隨意,我一向主張個性化布局的,主要以下幾個重要的控件得介紹一下:

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

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

我們先建一個公共類庫,這個類庫在主應用程序和所有擴展類庫都會引用,因為我們會在其中定義用 於規范組件行為的"憲法"(接口)。該類庫暫名為CommonLib,代碼如下,很簡單,不超過10 行。

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

新項一個類庫項目,名為ExtLibA,代碼如下:

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

分別生成這三個dll,還要包含一個CommonLib.dll,因為三個擴展庫都引用了它。然後把這幾個dll 分別放到一個文件夾中,大致如下圖所示。

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

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

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

然後,我們可以看看下面的執行結果。

三、 AggregateCatalog

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

然後我想,如果能保留前 面的三個擴展類的同時,也自動識別我寫到WinForm項目中的擴展類,那該多好啊。不怕,.NET的強大只 有你想不到,沒有它做不到的。這時候我把目光投向AggregateCatalog類,利用它可以將多個搜索范圍 合並,我們剛才的三個擴展是通過在一個文件夾中搜索的,而第四個擴展是寫到WinForm項目中的,還記 得前文中我們說過AssemblyCatalog類,它可以在某個程序集中尋找擴展類,所以第四個擴展類我們可以 在WinForm項目所在的程序集中查找。

也就是說,我們把AssemblyCatalog范圍和 DirectoryCatalog范圍進行組合。所以,把前面button1_Click的代碼改一下,變成以下這個樣子:

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

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

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

不知道大家看了我這幾篇有關MEF的吹牛散文之後, 會不會感歎MEF的神奇呢?不管大家會把MEF用在哪些地方,只要記住兩個原則:

在需要某項技術時就該當機立斷,否則反受其亂。

技術運用講求靈活,無招勝有招,就像李小龍的"李三腳"一樣,切忌濫用。

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

查看本欄目

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved