Я использую MEF для сопоставления интерфейса с классом реализации как способ DI. Например, я использую атрибут Import для интерфейса и Export для класса реализации. Насколько я понимаю, инфраструктура 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 создает их и вводит их клиентам по мере необходимости. Клиенты не должны вызывать свое распоряжение при завершении работы.