乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       昵稱10504424 2013-04-10

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

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

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

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

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

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

      涉及到MEF部件的創(chuàng)建規(guī)則,首先我們要看下【PartCreationPolicyAttribute】這個特性,因?yàn)椴考?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)入都使用一個實(shí)例,如果組合引擎中沒有該實(shí)例,則會創(chuàng)建,一旦有了,就不會再創(chuàng)建;【NonShared】和【Shared】相對應(yīng),即每次導(dǎo)入都創(chuàng)建一個新的實(shí)例,所有導(dǎo)入的實(shí)例都擁有自己唯一的狀態(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 {
      //默認(rèn)的是 Any
      [Import]
      public Student Student { get; set; }
      }
      }
      

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

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

      _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】的屬性,這里需要注意一下,如果要提供默認(rèn)值,必須標(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】,我們可以實(shí)現(xiàn)比較強(qiáng)類型的編程,再也不怕字符串拼錯,不過相比與【ExportMetadata】似乎是麻煩了一點(diǎn)點(diǎn)。

      三、部件組裝通知

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

      若要得到通知,我們只要實(shí)現(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ā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多