過去の関連記事
[C#][MEF]Managed Extensibility Framework入門 その1
[C#][MEF]Managed Extensibility Framework入門 その2
[C#][MEF]Managed Extensibility Framework入門 その3
[C#][MEF]Managed Extensibility Framework入門 その4
前回は、プロパティをExportして、それをImportすることをやりました。MEFでは、そのほかに、メソッドをExportすることが出来ます。
このメソッドのExportは、個人的にほかのDIコンテナでは見たことないと感じてる機能なので割りとお気に入りです。
メソッドにExportをつけると、DelegateとしてImportすることが出来ます。
例えば…
public void Foo(string value)
{
}
のようなメソッドにExport属性をつけると
public Action<string> Hoge { get; set; }
こんなプロパティにImportすることが出来ます。
特に難しいことはないと思うので、さくっとサンプルを書いてみようと思います。
MEFExportMethodという名前で、コンソールアプリケーションを作成してSystem.ComponentModel.Composition.dllを参照に追加します。
まずは、Importをするほうのプログラムを書いてみようと思います。
[Export]
public class FooProcess
{
[Import("FooProcessPreProcess", AllowDefault=true)]
public Action<string> PreProcess { get; set; }
public void Execute()
{
if (PreProcess != null)
{
// 前処理をしてから主処理を実行する
PreProcess("FooProcess");
}
Console.WriteLine("主処理実行!!");
}
}
PreProcessプロパティにImport属性がついています。FooProcessPreProcessという名前のものをImportするという定義にしました。AllowDefault=trueをつけることで、デフォルト値を許すようにしました。AllowDefaultをつけてないと、無理やりImportしようとして、次に書く予定のMainで例外が発生してしまいます。
次に、Exportのプログラムではなくて、Mainの流れを先に書いて動きを見てみます。
コンテナを作成して、FooProcessのインスタンスを取得してExecuteを呼び出しています。
class Program
{
static void Main(string[] args)
{
// 自身のアセンブリ内のクラスを自動で登録するコンテナを作成
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var container = new CompositionContainer(catalog);
// FooProcessを取得して処理実行
var process = container.GetExportedObject<FooProcess>();
process.Execute();
}
}
これを実行すると
と表示されます。とりあえず何も不思議なことはないはず!
次にメソッドをExportするクラスを書いてみようと思います。
public class CustomPreProcess
{
[Export("FooProcessPreProcess")]
public void PrintMessage(string message)
{
Console.WriteLine(message);
}
}
Action<string>型に入れれるように戻り値がvoidで、引数がstring1つのメソッドを定義しています。これにExport属性をつけて、Import側で指定したFooProcessPreProcessという文字列を指定します。
このクラスを追加して実行すると・・・
FooProcessが表示されているのがわかると思います。
こうすることで、任意の処理を差し込むポイントを簡単に作りこむことが出来ます。
個人的にこれはお気に入り!