4

Ich habe den NLayered Domain Driven Design Architecture-Leitfaden von Microsoft gelesen und möchte MEF als meinen DI-Container implementieren.MEF & korrekte Entkopplung einer N-geschichteten Domain Driven Design-Architektur

Ich wollte MEF durch Erstellen von 3 Projekten testen: ContractProject, das nur die Schnittstelle hat. ImplementationProject mit der Klasse, die diese Schnittstelle mit der Annotation Export [typeof (Interface)] implementiert. Und eine Konsolen-App, um das zu testen.

Gemäß den Dependency-Injection-Prinzipien sollte die High-Level-Schicht nicht auf die Low-Level-Schicht verweisen und umgekehrt. Sie sollten beide auf eine Abstraktionsschicht (Schnittstelle) verweisen.

Ich habe versucht, dies anzuwenden. Die Konsolenanwendung verweist auf das ContractsProject, und das Implementierungsprojekt verweist auf das ContractsProject. Aber MEF kann die EXPORT-Klasse nicht finden, wenn in der Assembly keine ImplenationProject-DLL vorhanden ist. Ich habe ein Tutorial gesehen, bei dem sie die DLL manuell zum Ordner bin der MainApp hinzufügen. Das Gute daran ist, dass Sie nicht direkt auf die Implementierungsmethoden zugreifen können, indem Sie "Referenz hinzufügen" dynamisch vermeiden, aber ich denke nicht, dass das das Richtige ist, da ich die DLL bei jeder Änderung manuell hinzufügen muss. Und mit einer NLayered Domain Driven Design Architektur App arbeitend brauche ich eine Menge DLLs.

Bedeutet dies, dass MEF nicht das richtige Werkzeug ist, das ich für Dependency Injection brauche? (Das Buch verwendet Unity)

Hier ist der Code:

namespace Contracts 
{ 
    public interface ISampleContract 
    { 
     string DoSomething(); 
    } 
} 

namespace Implementation 
{ 
    [Export(typeof(ISampleContract))] 
    public class Sample : ISampleContract 
    { 
     public string DoSomething() 
     { 
      return "I did something "; 
     } 
    } 
} 

Programm:

namespace Console 
{ 
    class Program 
    { 
     [Import] 
     public ISampleContract sample { get; set; } 

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

     public void Run() 
     { 
      var catalog = new AggregateCatalog(
      new AssemblyCatalog(Assembly.GetExecutingAssembly()), 
      new DirectoryCatalog(".")); 
      var container = new CompositionContainer(catalog); 

      container.ComposeParts(this); 
      Console.WriteLine(sample.DoSomething()); 
      Console.ReadKey(); 
     } 
    } 
} 

Wenn ich nicht die Umsetzung dll im Hauptprogramm verweisen, die ComposeParts() Sache schlägt fehl, weil die Exporte, die der Einschränkung entsprechen, nicht gefunden werden können. Gibt es einen Weg darum, ohne auf die DLL Bezug zu nehmen, oder sollte ich ein anderes DI-Tool vollständig auswählen? Wie zum Beispiel Unity?

EDIT Es funktioniert, wenn ich die Post-Build-Ereignis auf dem Implementierungsprojekt konfigurieren seine dll meiner Konsole bin zu kopieren. Ich bin mir nicht sicher, ob das eine gute Lösung ist.

copy /Y "$(TargetFileName)" "$(SolutionDir)Console\bin\Debug\$(ProjectName).dll" 
+2

BTW Ich bin mir nicht sicher, ob MEF die beste Wahl als Inversion des Steuercontainers ist ... –

+0

Ich fange gerade an, das zu begreifen. Scheint wie MEF bietet nicht die vollen Funktionalitäten eines DI-Containers noch an. – YL1

+0

Noch und nie ... –

Antwort

2

Sie sollten sicherstellen, dass Visual Studio die Implementierung.dll tatsächlich erstellt. Normalerweise passiert was passiert, wenn Sie Console.dll nur Console.dll und seine Abhängigkeiten erstellen. Jedes DI-Framework wird dieses Problem haben.

Eine Möglichkeit, dies zu beheben, gehen Sie zu Lösung -> Eigenschaften -> Projektabhängigkeiten und markieren dort die Build-Abhängigkeiten. (Hinweis: Die DLLs befinden sich in ihrem eigenen bin-Projektverzeichnis. Sie können sie als Post-Build-Schritt in einem Plugins-Verzeichnis bereitstellen.)

Zu einem späteren Zeitpunkt können Sie möglicherweise einige erweiterte Tools unabhängig voneinander einrichten Build und deploy Sie implementation.dll (würde ich nur in vernünftigen großen Projekten oder Projekten mit bestimmten Plugin-Anforderungen)

Bearbeiten: Der Nachteil der Einheit (und einige andere) ist, dass es oft zu einem riesigen entwickelt Mapping-Datei (zwingt Sie, sowohl eine Build- als auch eine Code-Abhängigkeit zu haben).

+0

Markiert die Build-Abhängigkeiten, aber es löst immer noch nicht mein Problem. MEF kann die Markierte Klasse Export nicht finden. Alle DLLs befinden sich in ihrer eigenen Projektablage, aber MEF kann die Datei "Implementierung.dll" immer noch nicht finden, wenn diese nicht im Ordner "Konsole" vorhanden ist. Beim Debuggen des Katalogs enthalten die geladenen Dateien nur die Datei Contract.dll. – YL1

+0

Sie funktioniert, wenn ich die Build-Ausgabe meiner Implementation.dll als den bin-Ordner meiner Konsole konfiguriere. Ist das eine gute Lösung? – YL1

+1

Ich würde alle anderen Projekte ausgeben, um in einem "plugins" -Verzeichnis auszugeben, und dann den Pfad des DirectoryCatalogs auf dieses Verzeichnis verweisen. (macht es einfacher zu sehen, was getrennt ist und was nicht) Ich habe dies oft durch einen Post-Build-Schritt mit xcopy gesehen. Obwohl ich persönlich kein großer Fan dieser Lösung bin. – Batavia

Verwandte Themen