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