MEF を使用して、DI の方法としてインターフェイスを実装クラスにマップします。たとえば、インターフェイスには Import 属性を使用し、実装クラスには Export 属性を使用します。私の理解では、MEF フレームワークは実装クラスのインスタンスを作成し、使用または自動注入のために MEF のコンテナーに保持します。
私の実装クラスのいくつかは IDispose インターフェイスを実装しています。インスタンスは MEF によって作成されるため、MEF が終了したときにコンポーネントが破棄される場合は、MEF がコンポーネントの Dispose メソッドを呼び出せるようにする必要があると思います。たとえば、私のアプリケーションでは、MEF のコンテナーへの参照を保持しています。アプリケーションが終了したら、コンテナーの Dispose メソッドを呼び出します。問題は、コンポーネントの Dispose が呼び出されないことです。
インポートとエクスポートのマッピングに関するコードの例を次に示します。
[Import]
private IMyInterface IComponent1 { get; set; }
....
[Export]
private IMyInterface Component {
get {
var instance = new MyImplemetation();
....
return instance;
}
}
....
同様の方法で、他のマッピングのインポートおよびエクスポート定義が他にも多数あります。この方法でマッピングを作成し、MEF が関係と、マップされたインスタンスを作成する方法を認識できるようにします。AssemblyCatalog を使用してマッピングを読み込むアプリケーションのコードを次に示します。
var catalog = new AggregateCatalog();
catalog.Add (new AssemblyCatalog(Assembly.GetExecutingAssembly());
var batch = new CompositionBatch();
batch.AddPart(catalog);
// MEF container has all the mappings
var container = new CompositionContainer(catalog);
....
// Get instance from container
var instance = container.GetExportedValue<IMyInterface>();
// my instance CTOR has a contructor with several other
// implementation instances injected by interface
// instance starts to do its job and coordinates others ...
instance.Start();
....
// Finally the job is done.
// Dispose the container explicitly there.
container.Dispose();
// But my components are never disposed
// this results some connections not being closed
// file streams not being closed...
ここで、インスタンスには、MEF によって CTOR を介して注入された他の多くのコンポーネントがあります。これらのコンポーネントには、MEF によって注入される他のコンポーネントも含まれています。問題は、一部のインスタンスが共有されているため、いつコンポーネントを破棄するかを決定するのが非常に難しいことです。1 つで Dispose を呼び出すと、他のユーザーはそれを使用できなくなります。この図でわかるように、インスタンスは MEF によって作成され、アプリケーション クラスに挿入されます。各コンポーネントは他のコンポーネントを認識してはならず、注入されたコンポーネントを使用してジョブを実行する必要があります。
アプリケーションが終了したとき、またはコンテナーが破棄されたときに、コンポーネントで Dispose を呼び出すように MEF に指示する場所/方法がわかりません。コンポーネントで Dispose を呼び出す必要がありますか? MEF がそれらを作成し、必要に応じてクライアントに挿入するため、それは正しくないと思います。クライアントは、ジョブを終了するときに Dispose を呼び出すべきではありません。