Managed Extensibility Framework でメソッドの Export と Import

Managed Extensibility Framework (以下 MEF) をさわる機会があったので、前から気になっていた「メソッドの Export と Import」を試してみました。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace MEFSample
{
    // クラスに Export 属性がないと、GetExportedValue で
    // Greeting インスタンスを取得できない。
    [Export]
    public class Greeting
    {
        // Export されたメソッドを、ここにセットする。
        // DI コンテナによって、"Greet" の名前付きで Export されたメソッドがセットされる。
        [Import("Greet")]
        public Func<string, string> Greet { get; set; }

        public string ExecuteGreet(string name)
        {
            return Greet(name);
        }
    }

    public class Morning
    {
        // このメソッドをエクスポートする。
        // DI コンテナによって、Greeting クラスの Greet プロパティにセットされる。
        [Export("Greet")]
        public string GoodMorning(string name)
        {
            return string.Format("Good Morning, {0}.", name);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            // このアセンブリに定義されているクラスを DI コンテナに登録する
            AssemblyCatalog catalog = new AssemblyCatalog(typeof(Program).Assembly);
            CompositionContainer container = new CompositionContainer(catalog);

            // 依存性注入済みのインスタンスを DI コンテナから取得する
            Greeting greeting = container.GetExportedValue<Greeting>();

            // メソッドがセットされているか確認
            string result = greeting.ExecuteGreet("Ichiro");
            Console.WriteLine(result); // => "Good Morning, Ichiro."

            Console.ReadLine();
        }
    }
}

わざわざインタフェースを用意しなくていいので便利!AssemblyCatalog を使って、アセンブリ内のクラスを一括で登録できるのも楽!!

メソッド単位で依存性を注入できる機能は、Unity には無いです。他の DI コンテナはどうだろう?Spring.NET とか。仕事でも使うかもしれないので、今から MEF について調べていこうかな。