2012-09-10 15 views
5

UPDATE: Sollte ich versuchen, es durch DI-Container oder es ist ein falsches Abstraktionsniveau hier?MEF und ABSTRACT FACTORY

Ich möchte ABSTRACT FACTORY mit MEF (.NET 4.5) implementieren.

Es ist nicht für mich arbeiten ...

Die Zusammensetzung bleibt unverändert. Die Änderungen wurden wegen der folgenden Fehler zurückgewiesen:

Die Zusammensetzung erzeugte einen einzigen Zusammensetzungsfehler. Die Ursache ist unten angegeben. Überprüfen Sie die CompositionException.Errors-Eigenschaft für weitere Informationen.

1) Es wurden keine Exporte gefunden, dass die Einschränkung überein:

ContractName Mef3.Factory

RequiredTypeIdentity Mef3.Factory in Resultierende: Kann nicht importieren ‚Mef3.Program._factory (ContractName =" Mef3 gesetzt. Factory ")" auf Teil "Mef3.Program".

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

Ist es der richtige Weg, es in MEF zu tun? Wie kann ich die ID an Foo/Bar ctors weiterleiten?

Der Code:

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 
{ 
} 

Antwort

1

Das Problem sieht von Ihrem [Import ("ID")] auf Foo und Bar verursacht werden. Es gibt keinen Export mit dem Vertragsnamen "Id". MEF erlaubt es im Allgemeinen nicht, Importe zur Laufzeit zu übergeben, Sie müssen in der Lage sein, das gesamte Diagramm zum Zeitpunkt der Erstellung zu erfüllen, sonst funktioniert es nicht. Wenn Sie MEF zum Ausführen dieses bestimmten Szenarios verwenden möchten, sollten Sie den Import-Konstruktor auf Foo und Bar entfernen und eine SetId-Methode für die Base-Klasse hinzufügen und Ihre Factory beim Aufruf von GetInstance aufrufen.

+0

Vielen Dank. Ich entfernte Foo/Bar ctor Parameter. Es löst dieselbe Ausnahme aus. –

+0

Es sieht seltsam aus, Property-Injection für ID zu verwenden, da es nicht optional ist. Denken Sie, dass ein solches Szenario nicht dem DI-Muster entspricht? Ist es MEF nur Problem? Sollte ich einen anderen DI-Container verwenden oder ist es nur eine falsche Abstraktionsebene für DI? –

+0

Hat jemand dieses Code-Snippet ausprobiert? Bin ich die einzige Person, für die es eine Ausnahme auslöst? –