2010-05-31 18 views
8

estoy empezando a usar MEF, y tengo una clase con varios constructores, así:parámetros del constructor constructores MEF con múltiples

[Export(typeof(ifoo))] 
class foo : ifoo { 
    void foo() { ... } 
    [ImportingConstructor] 
    void foo(object par1) { ... } 
} 

estoy usando catalog.ComposeExportedValue() la hora de componer para suministrar el valor par1 al segundo constructor:

... 
catalog.ComposeExportedValue(par1Value); 
catalog.ComposeParts(this); 
... 

Para mantener los componentes que estoy usando:

[ImportMany(typeof(ifoo))] 
public List<Lazy<ifoo, ifoometadata>> FooList { get; set; } 

Y para crear la instancia foo estoy usando la propiedad value, FooList[0].Value.

Everthing funciona bien, excepto que nunca se llama al segundo constructor de la clase foo. ¿Qué pasa?

¿Cómo selecciono el constructor que quiero usar cuando MEF crea una instancia de la clase?

+0

Tenga una mirada en http://stackoverflow.com/questions/2008133/mef-constructor-injection ... es no * exactamente * la misma pregunta, pero la respuesta aceptada arroja algo de luz sobre la importación de constructores que pueden ayudar. –

+0

sí, de hecho estoy usando la respuesta de Daniel Plaisted, el problema es que no puedo encontrar ningún ejemplo de creación de instancia de mef usando múltiples definiciones de constructor. – InterWAS

Respuesta

8

MEF debe usar el constructor en el que coloca el ImportingConstructorAttribute. No estoy seguro de lo que está sucediendo para ti, no pude reproducir el problema. Aquí está una prueba que muestra el uso de un ImportingConstructor en una clase que también tiene un constructor por defecto:

[TestClass] 
public class MefTest 
{ 
    public const string ConstructorParameterContract = "FooConstructorParameterContract"; 

    [TestMethod] 
    public void TestConstructorInjectionWithMultipleConstructors() 
    { 
     string ExpectedConstructorParameterValue = "42"; 

     var catalog = new TypeCatalog(typeof(Foo), typeof(FooImporter)); 
     var container = new CompositionContainer(catalog); 

     container.ComposeExportedValue<string>(ConstructorParameterContract, ExpectedConstructorParameterValue); 

     var fooImporter = container.GetExportedValue<FooImporter>(); 

     Assert.AreEqual(1, fooImporter.FooList.Count, "Expect a single IFoo import in the list"); 
     Assert.AreEqual(ExpectedConstructorParameterValue, fooImporter.FooList[0].Value.ConstructorParameter, "Expected foo's ConstructorParameter to have the correct value."); 
    } 
} 

public interface IFoo 
{ 
    string ConstructorParameter { get; } 
} 

[Export(typeof(IFoo))] 
public class Foo : IFoo 
{ 
    public Foo() 
    { 
     ConstructorParameter = null; 
    } 

    [ImportingConstructor] 
    public Foo([Import(MefTest.ConstructorParameterContract)]string constructorParameter) 
    { 
     this.ConstructorParameter = constructorParameter; 
    } 


    public string ConstructorParameter { get; private set; } 
} 

[Export] 
public class FooImporter 
{ 
    [ImportMany] 
    public List<Lazy<IFoo>> FooList { get; set; } 
} 
+0

Gracias Daniel, funciona de esa manera, pero ahora me he atascado en otro problema: La importación del constructor MEF no funciona cuando se usan clases derivadas, como si tenemos una clase Foo2 que hereda de Foo en su ejemplo y modificamos el resto para exportar/importar todas las clases derivadas de Foo, el constructor con parámetros de clase base (Foo) no se llama. Tal vez sea por diseño, para no verificar completamente los constructores de todas las clases base. Pero estoy usando una importación de campo en la clase base (Foo) y funciona, por lo que iam usa esta herramienta en lugar de las importaciones de constructores, al menos por ahora. Gracias por su ayuda Daniel. – InterWAS

+0

@InterWAS Es por diseño. Así es como funcionan los constructores en .NET: usted llama exactamente a un constructor cuando crea un objeto y no puede ser un constructor de clase base. Una clase derivada puede llamar al constructor de una clase base en su constructor. Las importaciones de propiedad/campo probablemente tengan más sentido en su caso. –

3

¿Está pasando una instancia de la clase foo al método ComposeExportedValue? En ese caso, el objeto ya se ha construido y no se puede volver a llamar al constructor, por lo que MEF ignorará las importaciones del constructor.

+0

No, en ComposeExportedValue() paso los valores que deseo inyectar en los constructores: catalog.ComposeExportedValue (par1Value); Mi problema es que cualquier parámetro de constructor supuesta es simplemente ignorado y la clase foo se instancia con solo el primer constructor. – InterWAS

Cuestiones relacionadas