實戰MEF(4):搜索范圍

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

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

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

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

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

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

  1. AssemblyCatalog

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

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

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

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

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

最后,在Main中進行組裝并測試調用。

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

?

二、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中選定的擴展類型。

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

?

三、AggregateCatalog

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

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

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

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

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

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

?

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

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

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

轉載于:https://www.cnblogs.com/tcjiaan/p/3301444.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376430.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376430.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376430.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android應用程序請求SurfaceFlinger服務創建Surface的過程分析

文章轉載至CSDN社區羅升陽的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7884628 前面我們已經學習過Android應用程序與SurfaceFlinger服務的連接過程了。連接上SurfaceFlinger服務之后,Android應用程序就可以請求…

Oracle面試題(基礎篇)

1. Oracle跟SQL Server 2005的區別? 宏觀上: 1). 最大的區別在于平臺,oracle可以運行在不同的平臺上,sql server只能運行在windows平臺上,由于windows平臺的穩定性和安全性影響了sql server的穩定性和安全性 2). oracl…

160 - 23 Chafe.1

環境 Windows xp sp3 工具 exeinfope ollydbg 查殼 用exeinfoe查殼 測試 可以從左下角狀態欄看出serial是無效的 直接OD載入字符串搜索 00401274 |. /75 17 jnz XChafe_1.0040128D 00401276 |. |6A 00 push 0x0 ; /Ti…

fis 詳細介紹(mac版) - 12-26沒有弄完 - 暫停

fis可以讓fe進入角色,而不必擔心底層的架構,性能得到優化。僅需三條命令,即可解決所有前端開發要求fis是nodejs寫的,發布在vpn(?)上下載 www.nodejs.org,并安裝nodejs,其中包括npm安裝fis: sudo…

用文件模擬CMOS保存數據

Hi3520D 芯片的內置CMOS最多只有5個字節可以用,但是我需要保存的數據有很多。 其中一個解決辦法是:可以把其他需要保存的數據放到一個配置文件中。每次寫的時候寫到配置文件,用的時候再從配置文件讀出數據即可。 用文件寫: 1 stat…

160 - 24 Chafe.2

環境: Windows xp sp3 工具 exeinfope OllyDBG 查殼 用exeinfope查殼,發現是沒有殼的。 測試 可以看出是從紅色框框里面的內容判斷serial是否有效 OD載入,字符串搜索可以得到: 004011EC . 55 pus…

十個利用矩陣乘法解決的經典題目

轉載自 Matrix67: The Aha Moments 好像目前還沒有這方面題目的總結。這幾天連續看到四個問這類題目的人,今天在這里簡單寫一下。這里我們不介紹其它有關矩陣的知識,只介紹矩陣乘法和相關性質。 不要以為數學中的矩陣也是黑色屏幕上不斷變化的綠色…

[C++]搞清楚類中構造與析構的順序

定義一個類對象時,首先根據初始化列表初始化類的成員(就算沒有顯式定義初始化列表,編譯器也會默認地初始化一次),然后運行構造函數。因此,類成員的構造函數必定先于類的構造函數運行。 class A { public:A(…

160 - 25 CodeZero.1

環境 Windows xp sp3 工具 exeinfope OllyDBG 查殼 無殼的VB程序 測試 運行程序后出現Nag窗口,所以這次的目標是除Nag窗口和找到serial 程序運行后彈出Nag窗口,并且等待5秒后按鈕的標題改成“Continue..”,點擊后才會彈出輸入seria…

WP8開發學習筆記動態修改啟動時導航的第一個頁面(如登錄前啟動頁為LoginPage,登錄后變為MainPage)...

很多時候我們需要在啟動程序的時候根據狀態改變初始導航頁面,比如程序在啟動的時候判斷用戶是否登錄, 如果未登錄則跳轉到LoginPage.xaml否則跳轉到MainPage界面。 這時候就要分析程序的啟動和導航的過程。 程序的啟動是App.xamlcs負責的。 App類的構造器…

6.數組和Hash表

當顯示多條結果時,存儲在變量中非常智能,變量類型會自動轉換為一個數組。 在下面的例子中,使用GetType()可以看到$a變量已經不是我們常見的string或int類型,而是Object類型,使用-is操作符來判斷是否是個數組&#xff0…

160 - 26 Colormaster

環境 Windows xp sp3 查殼 無殼的VB程序 測試: 輸入 Name:123456 Serial:12345 字符串搜索,找到判斷位置。 判斷Name的長度要大于等于5: 00402CBC . 33C9 xor ecx,ecx 00402CBE . 83F8 04 cmp eax,0x4 00…

Android 菜單(OptionMenu)大全 建立你自己的菜單

菜單是用戶界面中最常見的元素之一,使用非常頻繁,在Android中,菜單被分為如下三種,選項菜單(OptionsMenu)、上下文菜單(ContextMenu)和子菜單(SubMenu)&#…

160 - 27 Cosh.1

環境 Windows XP sp3 工具 exeinfope ollydbg 查殼 無殼的MFC程序 測試 彈出這個: 是一個CD-CHECK保護的程序。 字符串搜索,一下子就能來到這里: 0040121A . 68 9C304000 push Cosh_1.0040309C …

什么時候加上android.intent.category.DEFAULT

1、要弄清楚這個問題,首先需要弄明白什么是implicit(隱藏) intent什么是explicit(明確) intent。 Explicit Intent明確的指定了要啟動的Acitivity ,比如以下Java代碼: Intent intent new Intent(this, B.class) Implicit Intent沒有明確的指…

[BZOJ 2165] 大樓 【DP + 倍增 + 二進制】

題目鏈接:BZOJ - 2165 題目分析: 這道題我讀了題之后就想不出來怎么做,題解也找不到,于是就請教了黃學長,黃學長立刻秒掉了這道題,然后我再看他的題解才寫出來。。Orz 使用 DP 倍增 ,用狀態 f[…

oracle創建表空間

注意點: 1.如果在PL/SQL 等工具里打開的話,直接修改下面的代碼中[斜體加粗部分]執行 2.確保路徑存在,比如【D:\oracle\oradata\Oracle9i\】也就是你要保存文件的路徑存在 /*分為四步 */ /*第1步:創建臨時表空間 */ create tempor…

160 - 28 CoSH.2

環境 Windows xp sp3 工具 exeinfope ollydbg 查殼 無殼的MFC程序 測試 輸入 Nmae:123456 Serial:12345 點擊“CHECK”后彈出錯誤提示的消息框,然后程序自己結束掉 依然是字符串搜索: 004014DB . 8B1D FC214000 mov ebx,dword ptr ds…

負載均衡情況下獲取真實ip的方法

公司用了硬件負載均衡,最近發現日志中的用戶ip都為負載均衡器的ip,業務需要所以要改為用戶真實ip,下面記錄一下! 1、打開文件:/etc/httpd/conf/httd.conf。2、在文件中查找:”CustomLog”,找到如下配置塊: …

ASP.NET MVC5 + EF6 入門教程 (5) Model和Entity Framework

文章來源: Slark.NET-博客園 http://www.cnblogs.com/slark/p/mvc-5-ef-6-get-started-model.html 上一節:ASP.NET MVC 5 入門教程 (4) View和ViewBag 下一節:ASP.NET MVC5 EF6 入門教程 (6) View中的Razor使用 源碼下載:點我下…