MEF Programming Guide の上から順に見ていこうと思います。まずは、Hosting MEF in an application からです。
サンプルコードみて、動かしたら雰囲気わかるよね。気になったところを何個か書いてみます。
(最初はざっくり訳を書いてたんだけど、なんかダラダラ長くなったのと間違ってそうなので止めました)
気になった事1
一部抜粋
private void Compose() { var container = new CompositionContainer(); container.ComposeParts(this, new EmailSender()); }
ここで出てくる ComposeParts メソッドは、CompositionContainer のメソッドではなく、拡張メソッドでSystem.ComponentModel.Composition.AttributedModelServices に定義されているメソッドです。
AttributedModelServices.ComposeParts Method (System.ComponentModel.Composition)
どうも、属性付のオブジェクトから、なんやら色々とコンテナを構成するようです。
気になった事2
インジェクション したいプロパティ に Import 属性 ImportAttribute Class (System.ComponentModel.Composition) を付けて、インジェクションするクラスに Export 属性 ExportAttribute Class (System.ComponentModel.Composition)を付与するみたいです。
MSDN を見ると、ImportAttribute は プロパティ、フィールド、パラメータに付与出来、ExportAttribute は、クラス、メソッド、プロパティ、フィールドに付与出来る となっている。Export をメソッドに付与したらどうなるんだ?と思って試してみた。
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
public class Program
{
[Import("hoge")]
public Action<string> method;
public static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
public void Run()
{
Compose();
method("aaaa");
Console.ReadKey();
}
private void Compose()
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
public class HogeClass
{
[Export("hoge")]
public void HogeHoge(string message)
{
Console.WriteLine("hoge" + message);
}
}
デリゲートに対してインジェクションする際に、メソッドに Export を指定するのかな?
気になった事3
System.ComponentModel.Composition Namespace () を確認すると、Import は ImportAttribute 以外にも、
ImportingConstructorAttribute Class (System.ComponentModel.Composition) 、ImportManyAttribute Class (System.ComponentModel.Composition) があるみたい。
ImportMany も試してみた。
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
public class Program
{
[ImportMany]
private IEnumerable<IMessageSender> _senders;
public static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
public void Run()
{
Compose();
foreach (var sender in _senders)
{
sender.Send("aaaa");
}
Console.ReadKey();
}
private void Compose()
{
var 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 + " 1");
}
}
[Export(typeof(IMessageSender))]
public class EmailSender2 : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message + " 2");
}
}
ImportMany だと、配列 とか コレクションとかに使えるのかな?
なんか気になった事の方が長くなってしまった。資料を読み進めたら、疑問も解決出来るのかな〜。