Uso MEF para asignar la interfaz a la clase de implementación como una forma de DI. Por ejemplo, uso el atributo Importar para una interfaz y Exportar para la clase de implementación. Tengo entendido que el marco de MEF creará las instancias de la clase de implementación y las mantendrá en el contenedor de MEF para su uso o autoinyección.¿Desechar los componentes por contenedor MEF?
Algunas de mis clases de implementación implementan la interfaz IDispose. Dado que las instancias son creadas por MEF, creo que debería dejar que el MEF llame al método Dispose de los componentes si son desechables cuando el MEF está desactivado. Por ejemplo, en mi solicitud, tengo una referencia al contenedor del MEF. Cuando la aplicación termina, llamo al método Dispose del contenedor. El problema es que nunca se llama a los componentes 'Dispose'.
Éstos son algunos códigos de ejemplo acerca de la asignación de importación y exportación:
[Import]
private IMyInterface IComponent1 { get; set; }
....
[Export]
private IMyInterface Component {
get {
var instance = new MyImplemetation();
....
return instance;
}
}
....
Hay muchas otras definiciones de importación y exportación para otras asignaciones de la misma manera. Construyo mapeos de esta manera para que el MEF tenga el conocimiento de las relaciones y la forma de crear las instancias mapeadas. Aquí hay algunos códigos en mi solicitud para cargar asignaciones mediante 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...
aquí la instancia tiene muchos otros componentes inyectados a través CTOR por el MEF. Esos componentes también contienen otros componentes que son inyectados por el MEF. El problema es que es realmente difícil decidir cuándo deshacerse de los componentes, ya que algunas instancias se comparten. Si llamé a Dispose en uno, esto podría causar que otros no puedan usarlo. Como puede ver en esta imagen, las instancias son creadas por el MEF e inyectadas a mis clases de aplicaciones. Cada componente no debe tener ningún conocimiento de los demás, y debe usar componentes inyectados para hacer el trabajo.
No estoy seguro de dónde y cómo debo instruir al MEF para que llame a Dispose en los componentes cuando la aplicación finaliza o cuando se elimina el contenedor. ¿Debo llamar a Dispose en los componentes? No creo que sea correcto, ya que el MEF los crea e inyecta en los clientes según sea necesario. Los clientes no deben llamar a su Dispose al terminar sus trabajos.
Creo que Daniel lo explicó muy bien. Creé la instancia en mi get de propiedades Export. Tiene sentido mantener la instancia y limpiar desde allí. Prefiero poner Exportar en getter en lugar de class. Lo probaré y le diré si esto resolverá el problema. –