2010-10-17 18 views
5

Acabo de comenzar a usar MEF y he encontrado un problema temprano.MEF 'La exportación no es asignable al tipo' error

que tienen una interfaz llamada DataService:

namespace DataAccess 
{ 
    interface IDataService 
    { 
    string Name { get; } 
    string Description { get;} 

    List<String> GetPeople(); 
    } 
} 

Hay 2 implementaciones de esta interfaz, una para SQL Server y una para Oracle. A continuación se muestra la implementación de Oracle, la implementación de SQL Server es exactamente la misma.

namespace DataAccess 
{ 
[Export(typeof(IDataService))] 
[ExportMetadata("Name","Oracle")] 
[ExportMetadata("Description","Oracle Data Service")] 
public class Oracle : IDataService 
{ 

    #region IDataService Members 

    public string Name 
    { 
     get { return "Oracle"; } 
    } 

    public string Description 
    { 
     get { return "Provides data access to Oracle database"; } 
    } 

    public List<string> GetPeople() 
    { 
     return new List<String>() { "Oracle boo", "Oracle boo1" }; 
    } 

    #endregion 
} 
} 

El nombre y descripción propiedades son ahora desaparecido como he reemplazado con estos metadatos. Como puede ver, son objetos muy simples, quería asegurarme de que pudiera hacer que esto funcionara antes de comenzar a hacer el trabajo duro.

Este es el código que estoy utilizando para descubrir los conjuntos:

private static CompositionContainer _container; 
    private const string ASSEMBLY_PATTERN = "*.dll"; 
    private AggregateCatalog _catalog; 

    [ImportMany] 
    IEnumerable<DataAccess.IDataService> services { get; set; } 

    private void button3_Click(object sender, EventArgs e) 
    { 


     _catalog = new AggregateCatalog(
      new DirectoryCatalog(txtLibPath.Text, ASSEMBLY_PATTERN), 
      new AssemblyCatalog(Assembly.GetExecutingAssembly())); 
     _container = new CompositionContainer(_catalog); 
     _container.ComposeParts(this); 
     MessageBox.Show(services.Count().ToString()); 
    } 

Este es el error que se produce:

La composición produjo un solo error composición. La causa raíz se proporciona a continuación. Revise la propiedad CompositionException.Errors para obtener información más detallada.

1) La exportación 'DataAccess.Oracle (ContractName = "DataAccess.IDataService")' no es asignable para escribir 'DataAccess.IDataService'.

Como resultado: No se puede establecer la importación 'MEFTest.Form1.services (ContractName = "DataAccess.IDataService")' en la parte 'MEFTest.Form1'. Elemento: MEFTest.Form1.services (ContractName = "DataAccess.IDataService") -> MEFTest.Form1

No parece tener ningún sentido que no se puede asignar a la interfaz que ha sido diseñado para !

vez que este problema se resuelve, mi siguiente cuestión es cómo elegir una y consigue una instancia de ella ...

Respuesta

6

Parece que dos versiones diferentes de su ensamblaje contrato (el que tiene DataAccess.IDataService) son siendo cargado Uno es probablemente de tu ruta ejecutable y el otro de tu ruta de complementos. Toco este tema un poco en mi entrada de blog en How to Debug and Diagnose MEF Failures, y la página de MSDN en Best Practices for Assembly Loading entra en más detalles.

+0

Tenías razón Daniel, había vuelto a compilar IDataService para los proyectos que contenían los complementos SQLServer y Oracle, pero hacía referencia a una versión anterior en la aplicación principal. Moví el IDataService a un proyecto de biblioteca de clases separado y lo hice referencia de los tres proyectos y todo funciona perfectamente. Muchas gracias. – hermiod

+0

Este es un problema bastante tedioso. No es suficiente verificar solo su proyecto exe sino también los proyectos de todos los ensamblajes satelitales que carga. En mi caso, ejecuté proyectos de más de 50 ensamblajes satelitales y tuve dificultades para rastrear, lo que causa esta carga duplicada. Si no es una pista brillante de Daniel, no sé cuánto tiempo podría pasar resolviéndolo. –

0

Para mí esto tenía una solución muy simple.

Aquí está a link! eso explica la causa raíz.

En mi caso, bloqueé la versión de mi Asamblea, pero la versión de mi archivo viaja. La ID de mi paquete nuget coincide con la versión de mi archivo de ensamblaje.

El resultado final es que puedo construir continuamente, crear nuevos nugets y no tener este problema de interfaz MEF.

0

Debo decir que tuve un error así en un contexto completamente idiota. Accidentalmente, Extravié Directiva de exportación y la puse en la clase, pero no en una función dentro de la clase:

interface MyInterface 
{ 
    void MyFunction(); 
} 

public class MyClass : MyInterface 
{ 
    [Export(typeof(MyInterface))] 
    void MyFunction() { } 
} 

Sorprendentemente, el código compilado muy bien sin ninguna advertencia. ¡Pero luego pasé horas intentando descubrir por qué MEF falla en mi tonta errata!

Cuestiones relacionadas