2010-05-31 26 views
8

sto iniziando a utilizzare MEF, e ho una classe con più costruttori, in questo modo:MEF parametri del costruttore con Costruttori più

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

Sto usando catalog.ComposeExportedValue() durante la composizione di fornire il valore par1 alla seconda costruttore:

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

per contenere i componenti sto usando:

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

E per creare l'istanza foo sto utilizzando la proprietà value, FooList[0].Value.

Tutto funziona correttamente, tranne che il secondo costruttore della classe foo non viene mai chiamato. Cosa c'è che non va?

Come selezionare il costruttore che desidero utilizzare quando MEF istanzia la classe?

+0

Dai un'occhiata alla http://stackoverflow.com/questions/2008133/mef-constructor-injection ... è non * esattamente * la stessa domanda, ma la risposta accettata fa luce sull'importazione di costruttori che potrebbero aiutare. –

+0

sì, infatti sto usando la risposta di Daniel Plaisted, il problema è che non posso trovare alcun esempio di creazione di istanze di mef usando più definizioni di costruttore. – InterWAS

risposta

8

MEF dovrebbe utilizzare il costruttore su cui si inserisce ImportingConstructorAttribute. Non sono sicuro di ciò che sta accadendo per te, non ero in grado di riprodurre il problema. Ecco un test che mostra utilizzando un ImportingConstructor su una classe che ha anche un costruttore di default:

[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

Grazie Daniel, funziona così, ma ora mi sono bloccato su un altro problema: Importatore costruttore MEF non funziona quando si utilizzano classi derivate, come se abbiamo una classe Foo2 che eredita da Foo nell'esempio e si altera il resto per esportare/importa tutte le classi derivate da Foo, il costruttore con parametri della classe base (Foo) non viene chiamato. Forse è progettato, per non controllare i costruttori di tutte le classi base fino in fondo. Ma sto usando un campo di importazione in classe base (Foo) e funziona, quindi iam usando questo workround invece delle importazioni del costruttore, almeno per ora. Grazie per il tuo aiuto Daniel. – InterWAS

+0

@InterWAS È di progettazione. Ecco come funzionano i costruttori in .NET: si chiama esattamente un costruttore quando si crea un oggetto e non può essere un costruttore della classe base. Una classe derivata può chiamare il costruttore di una classe base nel suo costruttore. Le importazioni di proprietà/campo probabilmente hanno più senso nel tuo caso. –

3

Passate un'istanza della classe foo nel metodo ComposeExportedValue? In questo caso l'oggetto è già stato costruito e il costruttore non può essere richiamato, quindi MEF ignorerà le importazioni del costruttore.

+0

No, in ComposeExportedValue() inoltro i valori da iniettare nei costruttori: catalog.ComposeExportedValue (par1Value); Il mio problema è che tutti i parametri del costruttore in dotazione sono semplicemente ignorati e la classe foo è instantata usando solo il primo costruttore. – InterWAS

Problemi correlati