c# MEF框架(四 MEF高级进阶)
轉(zhuǎn)自:http://www.cnblogs.com/yunfeifei/p/3991330.html
好久沒有寫博客了,今天抽空繼續(xù)寫MEF系列的文章。有園友提出這種系列的文章要做個(gè)目錄,看起來方便,所以就抽空做了一個(gè),放到每篇文章的最后。
前面四篇講了MEF的基礎(chǔ)知識(shí),學(xué)完了前四篇,MEF中比較常用的基本已經(jīng)講完了,相信大家已經(jīng)能看出MEF所帶來的便利了。今天就介紹一些MEF中一些較為不常用的東西,也就是大家口中的所謂的比較高級(jí)的用法。
前面講的導(dǎo)出都是在每個(gè)類上面添加Export注解,實(shí)現(xiàn)導(dǎo)出的,那么有沒有一種比較簡(jiǎn)便的方法呢?答案是有的,就是在接口上面寫注解,這樣只要實(shí)現(xiàn)了這個(gè)接口的類都會(huì)導(dǎo)出,而不需要在每個(gè)類上面都寫注解。下面僅貼出接口和一個(gè)實(shí)現(xiàn)類的源碼,其余的模仿即可:
接口代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.Composition;namespace BankInterface {[InheritedExport]public interface ICard{//賬戶金額double Money { get; set; }//獲取賬戶信息string GetCountInfo();//存錢void SaveMoney(double money);//取錢void CheckOutMoney(double money);}}接口上面添加了[InheritedExport]標(biāo)記,沒錯(cuò),這個(gè)就是用在接口上面的注解。
下面給出一個(gè)實(shí)現(xiàn)類的代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using BankInterface; using System.ComponentModel.Composition;namespace BankOfChina {//[Export(typeof(ICard))]public class ZHCard : ICard{public string GetCountInfo(){return "Bank Of China";}public void SaveMoney(double money){this.Money += money;}public void CheckOutMoney(double money){this.Money -= money;}public double Money { get; set; }} }可以看到,我注釋掉了導(dǎo)出的注解,運(yùn)行后,依然可以看到,此類還是被導(dǎo)出了,運(yùn)行結(jié)果相信看過上一篇的都已經(jīng)知道了。
注意:這種方法雖然比較簡(jiǎn)單,但是只適用于比較簡(jiǎn)單的應(yīng)用,看完下面后,相信大家會(huì)意識(shí)到他的不足。
?
下面進(jìn)入今天的重點(diǎn):
?MEF中如何訪問某個(gè)具體的對(duì)象 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
前面我們講過在導(dǎo)出的時(shí)候,可以在[Export()]注解中加入名稱標(biāo)識(shí),從而識(shí)別某個(gè)具體的對(duì)象,然而這種方法只是用于頁面初始化的時(shí)候就行過濾,頁面打開后沒有導(dǎo)入的就再也導(dǎo)入不了了,就是說我們不能在導(dǎo)入的集合中分辨各自的不同,所有導(dǎo)入的類都是沒有標(biāo)識(shí)的。
為了給每一個(gè)類添加標(biāo)識(shí),我們要繼承ExportAttribute類,為他添加標(biāo)識(shí)屬性MetaData,首先來寫繼承自ExportAttribute的類,代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.Composition;namespace BankInterface {/// <summary>/// AllowMultiple = false,代表一個(gè)類不允許多次使用此屬性/// </summary> [MetadataAttribute][AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]public class ExportCardAttribute : ExportAttribute{public ExportCardAttribute():base(typeof(ICard)){}public string CardType { get; set; }} }代碼很簡(jiǎn)單,調(diào)用的父類的構(gòu)造方法,聲明了一個(gè)屬性CatdType,下面來添加一個(gè)接口,直接修改ICard接口文件,代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.Composition;namespace BankInterface {public interface ICard{//賬戶金額double Money { get; set; }//獲取賬戶信息string GetCountInfo();//存錢void SaveMoney(double money);//取錢void CheckOutMoney(double money);}public interface IMetaData{string CardType { get;}} }又添加了接口IMetaData,只有一個(gè)屬性,注意這個(gè)屬性要和剛寫的ExportCardAttribute類中的屬性名稱要一致,這樣才能實(shí)現(xiàn)導(dǎo)出。
下面利用我們的ExportCardAttribute屬性來標(biāo)記我們要導(dǎo)出的類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using BankInterface; using System.ComponentModel.Composition;namespace BankOfChina {[ExportCardAttribute(CardType="BankOfChina")]public class ZHCard : ICard{public string GetCountInfo(){return "Bank Of China";}public void SaveMoney(double money){this.Money += money;}public void CheckOutMoney(double money){this.Money -= money;}public double Money { get; set; }} }在這里,我們可以設(shè)置CardType的屬性,可以根據(jù)具體情況使用不同的數(shù)據(jù)類型。
現(xiàn)在,我們修改主程序的代碼為:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using BankInterface;namespace MEFDemo {class Program{//其中AllowRecomposition=true參數(shù)就表示運(yùn)行在有新的部件被裝配成功后進(jìn)行部件集的重組.[ImportMany(AllowRecomposition = true)]public IEnumerable<Lazy<ICard,IMetaData>> cards { get; set; }static void Main(string[] args){Program pro = new Program();pro.Compose();foreach (var c in pro.cards){if (c.Metadata.CardType == "BankOfChina"){Console.WriteLine("Here is a card of Bank Of China ");Console.WriteLine(c.Value.GetCountInfo());}if (c.Metadata.CardType == "NongHang"){Console.WriteLine("Here is a card of Nong Ye Yin Hang ");Console.WriteLine(c.Value.GetCountInfo());}}Console.Read();}private void Compose(){var catalog = new DirectoryCatalog("Cards");var container = new CompositionContainer(catalog);container.ComposeParts(this);}} }這里我用到了Lazy延遲加載機(jī)制(具體參見Lazy延遲加載),可以看到我們可以根據(jù)MetaData的屬性訪問到CardType屬性,從而判斷出Card的類型,從而區(qū)分導(dǎo)入的類型。
總結(jié)
以上是生活随笔為你收集整理的c# MEF框架(四 MEF高级进阶)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中Date和DateFormat
- 下一篇: AOE网