1. 程式人生 > >C#可擴展編程之MEF學習筆記(三):導出類的方法和屬性(轉)

C#可擴展編程之MEF學習筆記(三):導出類的方法和屬性(轉)

學習 說了 如何 mod ati dem ont num imp

前面說完了導入和導出的幾種方法,如果大家細心的話會註意到前面我們導出的都是類,那麽方法和屬性能不能導出呢???答案是肯定的,下面就來說下MEF是如何導出方法和屬性的。

  還是前面的代碼,第二篇中已經提供了下載鏈接,大家可以下載學習。

  首先來說導出屬性,因為這個比較簡單,和導出類差不多,先來看看代碼,主要看我加註釋的地方,MusicBook.cs中的代碼如下:

技術分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

namespace MEFDemo
{
   [Export("MusicBook")]
   public class MusicBook : IBookService
   {
      //導出私有屬性
      [Export(typeof(string))]
      private string _privateBookName = "Private Music BookName";

      //導出公有屬性
      [Export(typeof(string))]
      public string _publicBookName = "Public Music BookName";


      public string BookName { get; set; }

   }

   [Export("MathBook", typeof(IBookService))]
   public class MathBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "MathBook";
      }
   }

   [Export("HistoryBook", typeof(IBookService))]
   public class HistoryBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "HistoryBook";
      }
   }

}
技術分享

program.cs中的代碼如下:

技術分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFDemo
{
   class Program
   {
      [ImportMany("MathBook")]
      public IEnumerable<object> Services { get; set; }

      //導入屬性,這裏不區分public還是private
      [ImportMany]
      public List<string> InputString { get; set; }

      static void Main(string[] args)
      {
         Program pro = new Program();
         pro.Compose();
         if (pro.Services != null)
         {
            foreach (var s in pro.Services)
            {
               var ss = (IBookService)s;
               Console.WriteLine(ss.GetBookName());
            }
         }
         foreach (var str in pro.InputString)
         {
            Console.WriteLine(str);
         }

         Console.Read();
      }
      
      private void Compose()
      {
         var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
         CompositionContainer container = new CompositionContainer(catalog);
         container.ComposeParts(this);
      }
   }
}
技術分享

下面還用foreach遍歷輸出屬性的值,運行即可查看到結果。最後我會附上源碼供大家下載,這裏就不再截圖了。

下面說導出方法吧,同理無論是公有方法還是私有方法都是可以導出的,MusicBook代碼如下:

技術分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

namespace MEFDemo
{
   [Export("MusicBook")]
   public class MusicBook : IBookService
   {
      //導出私有屬性
      [Export(typeof(string))]
      private string _privateBookName = "Private Music BookName";

      //導出公有屬性
      [Export(typeof(string))]
      public string _publicBookName = "Public Music BookName";


      public string BookName { get; set; }

      //導出公有方法
      [Export(typeof(Func<string>))]
      public string GetBookName()
      {
         return "MusicBook";
      }

      //導出私有方法
      [Export(typeof(Func<int, string>))]
      private string GetBookPrice(int price)
      {
         return "$" + price;
      }
   }

   [Export("MathBook", typeof(IBookService))]
   public class MathBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "MathBook";
      }
   }

   [Export("HistoryBook", typeof(IBookService))]
   public class HistoryBook : IBookService
   {
      public string BookName { get; set; }

      public string GetBookName()
      {
         return "HistoryBook";
      }
   }

}
技術分享

program中的代碼如下:

技術分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFDemo
{
   class Program
   {
      [ImportMany("MathBook")]
      public IEnumerable<object> Services { get; set; }

      //導入屬性,這裏不區分public還是private
      [ImportMany]
      public List<string> InputString { get; set; }

      //導入無參數方法
      [Import]
      public Func<string> methodWithoutPara { get; set; }

      //導入有參數方法
      [Import]
      public Func<int,string> methodWithPara { get; set; }

      static void Main(string[] args)
      {
         Program pro = new Program();
         pro.Compose();
         if (pro.Services != null)
         {
            foreach (var s in pro.Services)
            {
               var ss = (IBookService)s;
               Console.WriteLine(ss.GetBookName());
            }
         }
         foreach (var str in pro.InputString)
         {
            Console.WriteLine(str);
         }

         //調用無參數方法
         if (pro.methodWithoutPara != null)
         {
            Console.WriteLine(pro.methodWithoutPara());
         }
         //調用有參數方法
         if (pro.methodWithPara != null)
         {
            Console.WriteLine(pro.methodWithPara(3000));
         }

         Console.Read();
      }
      
      private void Compose()
      {
         var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
         CompositionContainer container = new CompositionContainer(catalog);
         container.ComposeParts(this);
      }
   }
}
技術分享

導入導出方法用到了Func<T>委托,當然沒有返回值的話可以用Action<T>委托,關於委托這裏就不多說了,大家可以自行百度。

點擊這裏下載源碼

C#可擴展編程之MEF學習筆記(三):導出類的方法和屬性(轉)