この投稿は、Managed Extensibility FrameworkPreview2について言及しています。
そこで、MEFを実行して、以下に示す簡単な「HelloWorld」を作成しました。飛び込んで理解するのはとても簡単だったと言わざるを得ません。カタログシステムは素晴らしく、MEF自体を非常に簡単に拡張できます。アドインアセンブリのディレクトリをポイントして、残りを処理するのは簡単です。MEFの伝統であるalaPrismは確かに透けて見えますが、両方のフレームワークが構成に関するものであることを考えると、そうでない場合は奇妙だと思います。
私のクローに最もこだわるのは、_container.Compose()の「魔法」だと思います。HelloMEFクラスを見ると、greetingsフィールドがどのコードによっても初期化されていないことがわかります。これは面白いと感じます。私は、IoCコンテナーが機能する方法を好むと思います。この方法では、コンテナーにオブジェクトを作成するように明示的に要求します。ある種の「何もない」または「空の」汎用初期化子が適切であるのではないかと思います。すなわち
private IGreetings greetings = CompositionServices.Empty<IGreetings>();
これは、コンテナ構成コードが実行されて実際の「何か」で満たされるまで、少なくともオブジェクトを「何か」で満たします。わかりません。これは、私がいつも嫌っていたVisualBasicのEmptyまたはNothingキーワードを少し叩きます。他の誰かがこれについて何か考えを持っているなら、私はそれらを聞きたいです。多分それは私が乗り越える必要があるものです。大きな太い[インポート]属性が付いているので、完全な謎などではありません。
オブジェクトの存続期間を制御することは明らかではありませんが、エクスポートされたクラスに[CompositionOptions]属性を追加しない限り、デフォルトではすべてがシングルトンです。それでは、ファクトリまたはシングルトンのいずれかを指定できます。ある時点でPooledがこのリストに追加されるのを見るといいでしょう。
ダックタイピング機能がどのように機能するかはよくわかりません。ダックタイピングというよりは、オブジェクト作成時のメタデータインジェクションのようです。そして、追加できるアヒルは1つだけのようです。しかし、私が言ったように、これらの機能がどのように機能するかはまだはっきりしていません。うまくいけば、私は戻ってきて、後でこれを記入することができます。
DirectoryPartCatalogによってロードされるDLLをシャドウコピーするのは良い考えだと思います。現在、MEFがDLLを取得すると、DLLはロックされます。これにより、ディレクトリウォッチャーを追加し、更新されたアドインをキャッチすることもできます。それはかなり甘いでしょう...
最後に、アドインDLLがどの程度信頼されているか、およびMEFが部分的な信頼環境でどのように動作するか(または動作するかどうか)について心配しています。MEFを使用するアプリケーションには完全な信頼が必要だと思います。アドインを独自のAppDomainにロードすることも賢明かもしれません。System.AddInを少し叩くのは知っていますが、ユーザーアドインとシステムアドインを非常に明確に分離できます。
わかりました-十分な発砲。これがMEFとC#のHelloWorldです。楽しみ!
using System;
using System.ComponentModel.Composition;
using System.Reflection;
namespace HelloMEF
{
public interface IGreetings
{
void Hello();
}
[Export(typeof(IGreetings))]
public class Greetings : IGreetings
{
public void Hello()
{
Console.WriteLine("Hello world!");
}
}
class HelloMEF : IDisposable
{
private readonly CompositionContainer _container;
[Import(typeof(IGreetings))]
private IGreetings greetings = null;
public HelloMEF()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
}
public void Run()
{
greetings.Hello();
}
public void Dispose()
{
_container.Dispose();
}
static void Main()
{
using (var helloMef = new HelloMEF())
helloMef.Run();
}
}
}