2016-07-14 24 views
1

Ich versuche eine modulare Anwendung mit MEF zu erstellen.
Während des Komponierens scheint es jedoch SetExportedValue(..., ...) zu ignorieren, was dazu führt, dass es die Werte/Objekte, die ich brauche, nicht findet.Warum versagt MEF beim Teilekonstruktor?

Hier ist meine (anonymisierten und vereinfacht) Code:

interface IPlugin { } 

class MyClass 
{ 
    [ImportsMany(typeof(IPlugin))] 
    public IEnumerable<Lazy<IPlugin>> Plugins; 

    public LoadParts() 
    { 
     var ac = new AggregateCatalog(); 
     ac.Catalogs.Add(new AssemblyCatalog(typeof(PluginManager).Assembly)); 

     // imagine adding some DirectoryCatalogs here 

     var cc = new CompositionContainer(ac); 
     cc.ComposeExportedValue("MyValue", someinstance); 
     cc.ComposeParts(this); 
    } 
} 

[Export(typeof(IPlugin))] 
class MyPart : IPlugin 
{ 
    [ImportingConstructor] 
    public MyPart([Import("MyValue")] sometype arg) 
    { } 
} 

Daraus ergibt sich die folgende Fehlermeldung:

System.ComponentMode l.Composition Warnung: 1: Die ComposablePartDefinition 'MyNamespace.MyPart' wurde abgelehnt. Die Zusammensetzung bleibt unverändert. Die Änderungen wurden wegen der folgenden Fehler zurückgewiesen: Die Zusammensetzung erzeugte einen einzelnen 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 MyValue 
RequiredTypeIdentity somenamespace.sometype 

in Resultierende: Kann nicht importieren ‚MyNamespace.MyPart..ctor (Parametersatz =“ ... "ContractName =" ... ") 'auf Teil' MyNamespace.MyPart '.
Element: MyNamespace.MyPart..ctor (Parameter = "... " ContractName =" ... ") -> MyNamespace.MyPart -> Directory (Path =" ./")

Missverstehe ich, wie Teilekonstrukteure arbeiten?
Wie bekomme ich es, den Konstruktorparameter zu akzeptieren?


Edit für claification: someinstance ist eine spezifische Instanz von sometype. Ich möchte dem Container keinen Typ hinzufügen, sondern eine bestimmte Klasseninstanz.

Antwort

1

Ihre ImportingConstructor benötigt auch gültige Verträge und nicht nur Werte.

Dies ist ein Beispiel, wie mein Constructor funktioniert:

[ImportingConstructor] 
    public MyType([Import] IStatus status, [Import] IProtocoll protocoll) { 
    } 

Wie Sie sehen können, müssen Sie Schnittstellen wie contructor-Parameter verwenden.

Diese Schnittstellen sind schlicht und einfach ohne erforderliche Attribute.

Snippet IProtocoll

public interface IProtocoll { 

    IProtocollStateController ProtocollController { get; set; } 

    void WriteProtocoll(string action, string message, bool? result, Guid conditionId); 

    void WriteProtocoll(Protocoll protocoll); 

    List<Protocoll> GetAllProtocoll(); 
    } 

Ich schlage vor, Sie MyValue in einer gültigen Schnittstelle zu drehen. Dies könnte für eine einfache Saite etwas übertrieben sein, aber so funktioniert MEF.

Prost

+0

'" MyValue "' enthält jedoch eine bestimmte Klasseninstanz. Wenn ich nur diese Klasse "exportiere", erzeugt sie eine neue Instanz bei der Komposition, die ich nicht will, oder? –

+0

Hängt davon ab, wie Sie es tun. [This] (https://stefanhennek.wordpress.com/2011/08/30/mef-teil-6-constructor-injection/) ist in Deutsch, aber der Code ist Englisch und zeigt, wie es gemacht wird. Sie können außerdem Ihren Contruktor-Parameter zu einem Singleton machen, so dass Sie keine weiteren Instanzen haben – lokusking