Я использую 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...
Здесь у экземпляра есть много других компонентов, введенных MEF через CTOR. Эти компоненты также содержат другие компоненты, которые вводятся MEF. Проблема в том, что действительно сложно принять решение, когда удалять компоненты, поскольку некоторые экземпляры являются общими. Если я вызову Dispose для одного, это приведет к тому, что другие не смогут его использовать. Как вы можете видеть на этом рисунке, экземпляры создаются MEF и внедряются в классы моего приложения. Каждый компонент не должен знать других, и он должен использовать внедренные компоненты для выполнения своей работы.
Я не уверен, где и как я должен указать MEF для вызова Dispose для компонентов, когда приложение завершается или контейнер удаляется? Стоит ли вызывать Dispose для компонентов? Я не думаю, что это правильно, поскольку MEF создает их и вводит их клиентам по мере необходимости. Клиенты не должны вызывать Dispose по окончании работы.