我使用MEF將接口映射到實現類作爲DI的一種方式。例如,我使用Import屬性作爲接口,Export作爲實現類。我的理解是,MEF框架將創建實現類實例,並將它們保存在MEF的容器中供使用或自動注入。通過MEF容器處理組件?
我的一些實現類實現了IDispose接口。因爲實例是由MEF創建的,所以我認爲我應該讓MEF調用組件的Dispose方法,如果它們在MEF不在時可以丟棄的話。例如,在我的應用程序中,我持有對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...
這裏的實例已經通過CTOR由MEF注入許多其他部件。這些組件還包含由MEF注入的其他組件。問題在於,由於某些實例是共享的,因此很難決定何時處置組件。如果我打電話給Dispose,這會導致其他人無法使用它。正如你在這幅圖中看到的,實例是由MEF創建的,並注入到我的應用程序類中。每個組件不應該有任何其他知識,它應該使用注入的組件來完成這項工作。
我不確定在應用程序終止或處理容器時,我應該在哪裏/如何指示MEF調用Dispose?我應該在組件上調用Dispose嗎?我不認爲這是正確的,因爲MEF根據需要創建它們並將它們注入客戶。客戶在完成工作時不應該撥打Dispose。
我認爲Daniel很好地解釋了它。我在我的Export屬性獲取器中創建了實例。保持實例並從那裏清理是有意義的。我更喜歡將輸出放在getter而不是class上。我會測試它,並讓你知道這是否能解決問題。 – 2010-02-24 22:51:27