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 だと、配列 とか コレクションとかに使えるのかな?
なんか気になった事の方が長くなってしまった。資料を読み進めたら、疑問も解決出来るのかな〜。