MEF 編程指南(一):在應用中託管 MEF

在應用程序中託管(Hosing) MEF 涉及到建立組合容器(CompositionContainer) 實例,添加可組合部件(Composable Parts),包括應用程序宿主(Host)自己並進行組合(Composing)。ide

 
下面是託管涉及的步驟。
 
1.建立宿主(Host)類。下面的例子咱們使用控制檯應用程序,宿主(Host)類即 Program 類。
2.添加 System.ComponentModel.Composition 程序集引用。
3.添加如下 using 語句:using System.ComponentModel.Composition。
4.添加 Compose() 方法,建立容器實例,組合到宿主。
5.添加 Run() 方法調用 Compose()。
6.在 Main() 方法初始化宿主類。

注意:對於 ASP.NET 或者 WPF 應用程序,宿主類被運行時實例化,這些步驟都是沒有必要的。
 
代碼片斷:
 
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Run();
        }
 
        [Import]
        public IMessageSender MessageSender { get; set; }
 
        public void Run()
        {
            Compose();
            MessageSender.Send("Message Sent");
        }
 
        private void Compose()
        {
            var container = new CompositionContainer();
            container.ComposeParts(this, new EmailSender());
        }
    }
 
7.定義一個或多個導出點 (Exports) 宿主會進行導入。下面的代碼中,咱們定義了 IMessageSender 接口。咱們也經過申明 [System.ComponentModel.Composition.Export] 特性定義了 EmailSender 可組合部件(Composable Part)用以導出(export) IMessageSender。
 
    public interface IMessageSender
    {
        void Send(string message);
    }
 
    [Export(typeof(IMessageSender))]
    public class EmailSender : IMessageSender
    {
        public void Send(string message)
        {
            Console.WriteLine(message);
        }
    }
 
8.在宿主類中爲每一個導入點(Import)添加 [System.ComponentModel.Composition.Import] 特性,下例中 IMessageSender 做爲導入點(import)添加到 Program 類。
 
        [Import]
        public IMessageSender MessageSender { get; set; }
 
9.使用 MEF,咱們有多種途徑把部件(Part)添加到容器中。一種是直接添加現有的可組合部件(Composable Part)實例,而第二種,更經常使用的是經過使用目錄(Catalogs),咱們將在下面部分提到。
 
a.直接添加部件(Parts)到容器中

經過使用 ComposePart 擴展方法在 Compose() 方法中手動添加任意可組合部件(Composable Part)。在下例中,EmailSender 實例連同當前 Program 類的實例添加到容器(Container)。
 
        private void Compose()
        {
            var container = new CompositionContainer();
            container.ComposeParts(this, new EmailSender());
        }
 
b.使用 AssemblyCatalog 添加到容器
 
經過使用目錄(Catalog),容器自動處理部件(Parts)建立而不是顯示的添加。爲此,在 Compose() 方法建立目錄(Catalog)。接着建立解析器(Resolver)目錄(Catalog)而且傳遞給容器構造器(Container Constructor)。
 
下例中 AssemblyCatalog 由傳遞給構造器(Constructor)的執行程序集(Executing Assembly)建立。咱們沒有添加 EmailSender 的實例,它會從傳遞給當前的程序中目錄中(Catalog)獲取實例。
 
        private void Compose()
        {
            AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
 
當上面的代碼被編譯並執行,應用程序將由 IMessageSender 導入點(import)。Send() 方法會被調用在控制檯輸出「Message Send」。
 
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System;
using System.Reflection;
 
namespace HostingMefInAnApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Run();
        }
 
        [Import]
        public IMessageSender MessageSender { get; set; }
 
        public void Run()
        {
            Compose();
            MessageSender.Send("Message Sent");
        }
 
        private void Compose()
        {
            AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
    }
 
    public interface IMessageSender
    {
        void Send(string message);
    }
 
    [Export(typeof(IMessageSender))]
    public class EmailSender : IMessageSender
    {
        public void Send(string message)
        {
            Console.WriteLine(message);
        }
    }
}
相關文章
相關標籤/搜索