日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

MEF核心筆記(4)細說MEF中的Attribute [下]

 昵稱10504424 2013-04-10

MEF核心筆記(4)細說MEF中的Attribute [下]

今天,我們繼續(xù)MEF的學(xué)習(xí)記錄,這次內(nèi)容感覺比較重要,所以,特別放到單獨一篇來說,這也是MEF很有特色的地方,相信這其中的亮點,會讓你感觸良多的。

本篇主要有以下幾節(jié)內(nèi)容:

  • 部件的創(chuàng)建規(guī)則
  • 元數(shù)據(jù)和元數(shù)據(jù)視圖
  • 部件組裝通知
  • 總結(jié)

一、部件的創(chuàng)建規(guī)則

我們知道,在目前主流的IoC框架里,注入對象的創(chuàng)建都可以進行個性化配置,例如是否以單例方式創(chuàng)建(也就是共享一個對象,給所有需要注入的地方調(diào)用),不僅如此,如果屬性【Remoting】技術(shù)的朋友應(yīng)該也會接觸到服務(wù)對象的實例創(chuàng)建,另外WCF服務(wù)對象也亦是如此,他們都有各自的創(chuàng)建規(guī)則。同樣,MEF的部件也有它的創(chuàng)建規(guī)則。

涉及到MEF部件的創(chuàng)建規(guī)則,首先我們要看下【PartCreationPolicyAttribute】這個特性,因為部件創(chuàng)建的規(guī)則,主要是靠該特性來控制的。該特性只有一個屬性【CreationPolicy】,類型為【System.ComponentModel.Composition.CreationPolicy】的枚舉:

image

對應(yīng)的【ImportAttribute】、【ImportManyAttribute】,都有一個【RequiredCreationPolicy】的屬性,類型也是此枚舉。從這里我們就不難看出,使用【PartCreationPolicyAttribute】我們可以指定導(dǎo)出部件的創(chuàng)建規(guī)則,通過導(dǎo)入的【RequiredCreationPolicy】的屬性我們可以設(shè)定導(dǎo)入類型的創(chuàng)建規(guī)則。

根據(jù)【CreationPolicy】枚舉的值,我們很容易就能看出其代表的意義,【Shared】代表共享部件,即單例,所有的導(dǎo)入都使用一個實例,如果組合引擎中沒有該實例,則會創(chuàng)建,一旦有了,就不會再創(chuàng)建;【NonShared】和【Shared】相對應(yīng),即每次導(dǎo)入都創(chuàng)建一個新的實例,所有導(dǎo)入的實例都擁有自己唯一的狀態(tài),數(shù)據(jù)不共享;【Any】只是為了匹配導(dǎo)入導(dǎo)出,有下面一張匹配表:

導(dǎo)出的CreationPolicy 導(dǎo)入的CreationPolicy
Any Any、NonShared、Shared
NoneShared NoneShared、Any
Shared Shared、Any

只有滿足上面這張表,導(dǎo)入導(dǎo)出才會匹配,下面我們做一個很簡單的示例:

namespace MEFTest {
class Program {
private static CompositionContainer _container;
static void Main(string[] args) {
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
_container = new CompositionContainer(catalog);
var studentManager1 = _container.GetExportedValue<StudentManager>();
var studentManager2 = _container.GetExportedValue<StudentManager>();
Console.WriteLine(object.ReferenceEquals(studentManager1, studentManager2));
Console.WriteLine(object.ReferenceEquals(studentManager1.Student,
studentManager2.Student));
while (true) {
Console.ReadLine();
}
}
}
//單例導(dǎo)出
[Export, PartCreationPolicy(CreationPolicy.Shared)]
public class Student {
public string Name { get; set; }
public int Age { get; set; }
}
//非單例導(dǎo)出
[Export, PartCreationPolicy(CreationPolicy.NonShared)]
public class StudentManager {
//默認的是 Any
[Import]
public Student Student { get; set; }
}
}

最后輸出的是一個false和true,看懂了這個示例,你就看懂整個創(chuàng)建規(guī)則了,如果沒有看懂,抱歉,只能說明,我的示例寫得太爛了。

此外,我們可以預(yù)先在容器中定義導(dǎo)出,這樣的定義不需要【Export】特性描述類型,并且這樣輸出的永遠是單例:

_container.ComposeExportedValue<DateTime>(DateTime.Now);
Console.WriteLine(_container.GetExportedValue<DateTime>());

二、元數(shù)據(jù)和元數(shù)據(jù)視圖

在MEF中,我們可以在導(dǎo)出部件時附加一些數(shù)據(jù),而這些附加導(dǎo)出的數(shù)據(jù)就是元數(shù)據(jù),附加導(dǎo)出數(shù)據(jù)的結(jié)構(gòu)就是元數(shù)據(jù)視圖,這是我覺得MEF中,最令人激動的功能。

導(dǎo)出元數(shù)據(jù),我們使用【ExportMetadata】特性,設(shè)置該特性的【Name】和【Value】,即可導(dǎo)出對應(yīng)的元數(shù)據(jù),我們以示例來說:

class Program {
private static CompositionContainer _container;
static void Main(string[] args) {
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
_container = new CompositionContainer(catalog);
var studentManager = _container.GetExportedValue<StudentManager>();
Console.WriteLine(studentManager.Student.Metadata.ClassName);
while (true) {
Console.ReadLine();
}
}
}
public interface IClassMetadata {
string ClassName { get; }
[DefaultValue("")]
string OtherInfo { get; }
}
[Export]
[ExportMetadata("ClassName", "一年級三班")]
public class Student {
public string Name { get; set; }
public int Age { get; set; }
}
[Export]
public class StudentManager {
[Import]
public Lazy<Student, IClassMetadata> Student { get; set; }
}

在該示例中,【IClassMetadata】即是元數(shù)據(jù)視圖,我們導(dǎo)出的元數(shù)據(jù)必須滿足該接口格式,否則【StudentManager】的【Improt】就會失敗。我們在【Student】類上只導(dǎo)出了【ClassName】,而我們的元數(shù)據(jù)視圖中還有一個【OtherInfo】的屬性,這里需要注意一下,如果要提供默認值,必須標(biāo)記上【DefaultValue】,否則如果不賦值(導(dǎo)出)的話,就匹配不了該元數(shù)據(jù)視圖,也就是說,如果我們將【DefaultValue】去掉,該程序就不會正確執(zhí)行了(【StudentManager】的【Improt】會失?。?。

除了使用【ExportMetadata】特性導(dǎo)出元數(shù)據(jù)外,我們還可定義自己的導(dǎo)出特性來導(dǎo)出元數(shù)據(jù),我們可以繼承【ExportAttribute】,并且一定要有【MetadataAttribute】特性,以上的示例,我們可以改成這樣:

public interface IClassMetadata {
string ClassName { get; }
string OtherInfo { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class)]
public class ExportStudent : ExportAttribute, IClassMetadata {
public ExportStudent()
: base() { }
public ExportStudent(string contractName)
: base(contractName) { }
public ExportStudent(Type contractType)
: base(contractType) { }
public ExportStudent(string contractName, Type contractType)
: base(contractName, contractType) { }
public string ClassName { get; set; }
//如果可選,必須要加上
[DefaultValue("")]
public string OtherInfo { get; set; }
}
[ExportStudent(ClassName = "一年級三班")]
public class Student {
public string Name { get; set; }
public int Age { get; set; }
}

通過繼承【ExportAttribute】,我們可以實現(xiàn)比較強類型的編程,再也不怕字符串拼錯,不過相比與【ExportMetadata】似乎是麻煩了一點點。

三、部件組裝通知

這是個比較簡單,但又很有用的功能,特別是在我們需要完成一些自動化的操作時(例如日志)。部件組裝通知,就是當(dāng)某個組件引用的部件都能滿足導(dǎo)入,在返回已經(jīng)組裝完成的組件之前,先通知該組件。

若要得到通知,我們只要實現(xiàn)【IPartImportsSatisfiedNotification】接口即可,該接口有一個【OnImportsSatisfied】的方法,即通知組件部件組裝的地方。請看簡單的示例:

class Program {
private static CompositionContainer _container;
static void Main(string[] args) {
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
_container = new CompositionContainer(catalog);
var studentManager = _container.GetExportedValue<MyComponent>();
while (true) {
Console.ReadLine();
}
}
}
[Export]
class MyComponent : IPartImportsSatisfiedNotification {
public void OnImportsSatisfied() {
Console.WriteLine("OK!~");
}
}

該示例很簡單,但也將【IPartImportsSatisfiedNotification】淋漓盡致的體現(xiàn)了,由于【MyComponent】滿足了組裝條件,所以該通知一定能得到執(zhí)行。

四、總結(jié)

這一篇和前一篇是MEF非常核心的內(nèi)容,了解到這里,我們基本上已經(jīng)完全可以勝任MEF的開發(fā)使用了。后續(xù)打算開發(fā)一個程序,來深入體會MEF具體使用,以及設(shè)計層面上的思想,大家一起期待吧。

作者:MKiller
出處:http://www.cnblogs.com/prinsun/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多