2012-09-10 13 views
5

ACTUALIZACIÓN: ¿Debería tratar de manejarlo con un contenedor DI o aquí tiene un nivel de abstracción incorrecto?MEF y FACTORY ABSTRACT

Me gustaría implementar ABSTRACT FACTORY utilizando MEF (.NET 4.5).

No funciona para mí ...

la composición permanece sin cambios. Los cambios se rechazaron debido a los siguientes errores:

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

1) No hay exportaciones que coincidan con la restricción:

ContractName Mef3.Factory

RequiredTypeIdentity Mef3.Factory El resultado es: No se puede establecer la importación 'Mef3.Program._factory (ContractName = "Mef3. Fábrica ")" en la parte "Mef3.Program".

Elemento: Mef3.Program._factory (ContractName = "Mef3.Factory") -> Mef3.Program

¿Es la forma correcta de hacerlo en el MEF? ¿Cómo puedo enviar la identificación a Foo/Bar ctors?

El código:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var program = new Program(); 
     program.Run(); 
    } 

    readonly CompositionContainer _container; 

    public Program() 
    { 
     var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 
     _container = new CompositionContainer(catalog); 
     _container.ComposeParts(this); 
    } 

    [Import] 
    public Factory _factory; 

    public void Run() 
    { 
     var foo = _factory.GetInstance("foo", 123); 
     Console.WriteLine(foo is Foo); 
    } 
} 

[Export] 
public class Factory 
{ 
    private readonly ExportFactory<Foo> _fooFactory; 
    private readonly ExportFactory<Bar> _barFactory; 

    [ImportingConstructor] 
    public Factory(ExportFactory<Foo> fooFactory, ExportFactory<Bar> barFactory) 
    { 
     _fooFactory = fooFactory; 
     _barFactory = barFactory; 
    } 

    public Base GetInstance(string name, int id) 
    { 
     switch (name) 
     { 
      case "foo": 
       return _fooFactory.CreateExport().Value; 

      case "bar": 
       return _barFactory.CreateExport().Value; 
     } 

     throw new ArgumentException(); 
    } 
} 

public class Foo : Base 
{ 
    [ImportingConstructor] 
    public Foo([Import("Id")] int id) 
    { 
    } 
} 

public class Bar : Base 
{ 
    [ImportingConstructor] 
    public Bar([Import("Id")] int id) 
    { 
    } 
} 

[InheritedExport] 
public abstract class Base 
{ 
} 

Respuesta

1

El problema parece ser causado por su [Importación ("ID")] en Foo y Bar. No hay exportación con un nombre de contrato de "Id". MEF en general no le permite pasar importaciones en tiempo de ejecución, necesita poder satisfacer todo el gráfico en el momento de la composición o de lo contrario no funcionará. Si desea utilizar MEF para lograr este escenario en particular, debe eliminar ImportingConstructor en Foo y Bar, agregar un método SetId en la clase Base y hacer que su fábrica lo llame cuando llame a GetInstance.

+0

Gracias. Eliminé los parámetros de Foo/Bar ctor. Lanza la misma excepción. –

+0

Parece extraño usar la inyección de propiedades para ID, ya que no es opcional. ¿Crees que ese escenario no cumple con el patrón DI? ¿Es solo MEF un problema? ¿Debo usar otro contenedor DI o solo es un nivel de abstracción incorrecto para DI? –

+0

¿Alguien ha probado este fragmento de código? ¿Soy la única persona a la que arroja la excepción? –