8

ACTUALIZACIÓNMEF = ¿puede experimentar frustración?

Como he tratado de conseguir MEF trabajando a lo largo de mi solicitud, ya voy a través de más una más lugares donde yo no lo entiendo por qué no es la creación automática de la biblioteca de mi cuando yo esperaba que . Creo que todo vuelve a lo que Reed estaba diciendo sobre la necesidad de MEF para crear todo. Así que ahora mismo, tengo una clase de lector de XML que necesita usar mis CandySettings, pero a pesar de que su propiedad ICandySettings tiene el atributo [Importar], no se importa. Primero descubrí que [Importar] no funciona en estática, así que cambié esto. Pero después de eso, todavía no funcionó. Creo que es porque creo manualmente el objeto lector XML, y lo que MEF quiere que haga es [Importar] el lector XML ... lo que significa que ahora también tengo que tener una interfaz para eso.

Es casi como usar IoC (o para MEF, al menos), es un asunto de todo o nada. No se puede usar arbitrariamente aquí y allá porque, en última instancia, MEF necesita crear cualquier clase en la que desee inyectar propiedades.

¡Corríjame si me equivoco!


Post original

Bueno, todavía no es tan malo. :) Pero tengo preguntas después de que Reed me haya señalado en MEF como una alternativa potencial al IoC (y hasta ahora se ve bastante bien).

Considere el siguiente modelo: alt text http://bit.ly/9W0sHt

Como se puede ver, tengo una aplicación, y esta aplicación utiliza plugins (gritos, se perdió esa asociación!). Tanto la aplicación como los complementos requieren el uso de un objeto de tipo CandySettings, que se encuentra en otro ensamblaje.

Primero intenté usar el método ComposeParts en MEF, pero la única manera en que podía hacer que esto funcionara era hacer algo como esto en el plugin código.

var container = new CompositionContainer(); 
container.ComposeParts(this, new CandySettings()); 

Pero esto no tiene ningún sentido, porque ¿por qué iba a querer crear la instancia de CandySettings en el plugin? Debería estar en la aplicación. Pero si lo pongo en el código de la aplicación, entonces el complemento no descubre mágicamente cómo llegar a ICandySettings, aunque estoy usando [Importar] en el complemento y [Exportar] en CandySettings. EDITAR (probablemente porque debería estar llamando ComposeParts() de la App y luego pasándole el plugin?)

La forma en que lo hice fue utilizar de MEF DirectoryCatalog, porque esto permite que el plug-in, cuando se construyó, escanear todos los ensamblajes en la carpeta actual e importar automágicamente todo lo que está marcado con el atributo [Importar]. Así que parece que esto, y potencialmente en cada plugin:

var catalog = new DirectoryCatalog("."); 
var container = new CompositionContainer(catalog); 
container.ComposeParts(this); 

Esta totalmente funciona muy bien, pero no puedo evitar pensar que esto no es como el MEF estaba destinado a ser utilizado?

+0

Recuerdo que existían algunas restricciones reales al utilizar MEF, y que su uso previsto era para aplicaciones como Visual Studio, etc., y por lo tanto, debería asegurarse de que su diseño coincida con sus suposiciones primero. Básicamente, dijo que esto "no es para todos". http://codebetter.com/blogs/glenn.block/archive/2009/08/16/should-i-use-mef-for-my-general-ioc-needs.aspx –

+0

Creo que todo saldrá bien , pero esta es una de esas cosas que espero de un programador de .NET ahora. Hay tantas maneras de despellejar a un gato, y básicamente la única manera en que alguna vez lo descubrirás es probar varias opciones. Hasta ahora, he implementado mi código en MEF y Unity, y ambos funcionarán, aunque todavía no estoy seguro de que la forma en que lo hice en cualquiera de los frameworks sea 100% correcta. – Dave

+0

¿Puede agregar el mensaje de error que recibe de 'ComposeParts', el código que está utilizando para inicializar su contenedor y el código que está utilizando para exportar/importar? –

Respuesta

8

El "truco" aquí es que desea que MEF cree sus complementos para usted.

La forma en que va a hacer esto es tener su propia aplicación componer, con los tipos plugin especificado:

class PluginRepository 
{ 
    [ImportMany(typeof(IPlugin))] 
    IEnumerable<IPlugin> Plugins { get; set; } 
} 

Si hace esto, y tienen MEF Encuadre la clase de "depósito", MEF construirá los objetos. A continuación, redactará automáticamente esos elementos a medida que los construye, de modo que ICandySettings se compondrán sin ninguna intervención.

Solo tiene que "componer" manualmente un objeto si MEF no lo está construyendo por usted.

+0

Ok, intentaré eso, ¡gracias! Si eso funciona en la aplicación de prueba, entonces el resultado final probable en la aplicación real es reemplazar mi cargador de complementos (el que actualmente usa Reflection) con un código como el suyo, ¿no? – Dave

+0

@Dave: Sí. Realmente no necesitas usar la reflexión en absoluto. MEF lo hace extremadamente simple, muy confiable y muy corto en el código ... –

+0

@Reed: Ok, entonces tenía mi aplicación [Importar] mi interfaz de complemento. Mi aplicación también usa DirectoryCatalog para buscar todas las importaciones de ensamblajes. My Plugin [Import] s ICandySettings, y mi biblioteca CandySettings exporta a través del atributo [Exportar (typeof (ICandySettings))]. Pasé por el código y, en la aplicación, confirmé que el objeto CandySettings y el objeto Plugin se instanciaron. Pero el constructor del complemento necesita CandySettings, y en el momento de la construcción, CandySettings no se resuelve ... ¿es esto una limitación o crees que conecté algo mal? Obtengo una excepción nula – Dave