(Im Zusammenhang mit dieser Frage, EF4: Warum muss die Proxy-Erstellung aktiviert werden, wenn das verzögerte Laden aktiviert ist? )
Ich bin neu bei DI, also nimm es mit. Ich verstehe, dass der Container für die Instanziierung aller meiner registrierten Typen zuständig ist. Dazu ist jedoch ein Verweis auf alle DLLs in meiner Lösung und deren Verweise erforderlich.
Wenn ich keinen DI-Container verwenden würde, müsste ich in meiner MVC3-App nicht auf die EntityFramework-Bibliothek verweisen, sondern nur auf meine Business-Schicht, die auf meine DAL / Repo-Schicht verweist.
Ich weiß, dass am Ende des Tages alle DLLs im bin-Ordner enthalten sind, aber mein Problem besteht darin, dass ich explizit über "Verweis hinzufügen" in VS darauf verweisen muss, um einen WAP mit allen erforderlichen Dateien veröffentlichen zu können.
Antworten:
Ja, genau das ist die Situation, die DI so schwer zu vermeiden ist :)
Bei eng gekoppeltem Code hat jede Bibliothek möglicherweise nur wenige Referenzen, aber auch diese haben andere Referenzen, wodurch ein tiefes Diagramm von Abhängigkeiten wie folgt erstellt wird:
Da die Abhängigkeitsgraphen tief ist, bedeutet dies, dass die meisten Bibliotheken entlang viele andere Abhängigkeiten ziehen - zum Beispiel in dem Diagramm - Bibliothek C schleppt Bibliothek H, Bibliothek E, Bibliothek J, Bibliothek M, Bibliothek K und Bibliothek N . Dies macht es schwieriger, jede Bibliothek unabhängig von den anderen wiederzuverwenden - beispielsweise beim Testen von Einheiten .
In einer lose gekoppelten Anwendung wird der Abhängigkeitsgraph jedoch stark verschoben , indem alle Verweise auf die Kompositionswurzel verschoben werden :
Wie die grüne Farbe zeigt, ist es jetzt möglich, Bibliothek C wiederzuverwenden, ohne unerwünschte Abhängigkeiten mit sich zu ziehen.
Doch alles , was gesagt, mit vielen DI Container, die Sie nicht haben , um harte Verweise auf alle benötigten Bibliotheken hinzufügen. Stattdessen können Sie die späte Bindung entweder in Form eines konventionellen Assembly-Scans (bevorzugt) oder einer XML-Konfiguration verwenden.
Wenn Sie dies tun, müssen Sie jedoch daran denken, die Assemblys in den Bin-Ordner der Anwendung zu kopieren, da dies nicht mehr automatisch geschieht. Persönlich finde ich diese zusätzliche Anstrengung selten wert.
Eine ausführlichere Version dieser Antwort finden Sie in diesem Auszug aus meinem Buch Dependency Injection, Principles, Practices, Patterns .
quelle
Selbst wenn Sie einen DI-Container verwenden, müssen Sie Ihr MVC3-Projekt nicht auf EF verweisen lassen, aber Sie entscheiden sich (implizit) dafür, indem Sie den Kompositionsstamm (den Startpfad, in dem Sie Ihre Objektdiagramme erstellen) in Ihrem MVC3-Projekt implementieren. Wenn Sie Ihre Architekturgrenzen mithilfe von Assemblys sehr streng schützen möchten, können Sie Ihre Präsentationslogik entweder in ein anderes Projekt verschieben.
Wenn Sie die gesamte MVC-bezogene Logik (Controller usw.) aus dem Startprojekt in eine Klassenbibliothek verschieben, bleibt diese Präsentationsschicht-Assembly vom Rest der Anwendung getrennt. Ihr Webanwendungsprojekt selbst wird zu einer sehr dünnen Hülle mit der erforderlichen Startlogik. Das Webanwendungsprojekt ist das Composition Root, das auf alle anderen Assemblys verweist.
Das Extrahieren der Präsentationslogik in eine Klassenbibliothek kann die Arbeit mit MVC erschweren. Es wird schwieriger sein, alles zu verkabeln, da sich die Controller nicht im Startprojekt befinden (während Ansichten, Bilder und CSS-Dateien wahrscheinlich im Startprojekt verbleiben müssen). Dies ist wahrscheinlich machbar, die Einrichtung dauert jedoch länger.
Aufgrund der Nachteile empfehle ich generell, nur die Kompositionswurzel im Webprojekt zu belassen. Viele Entwickler möchten nicht, dass ihre MVC-Assembly von der DAL-Assembly abhängt, aber das ist kein wirkliches Problem. Vergessen Sie nicht, dass Assemblys ein Bereitstellungsartefakt sind . Sie teilen Code in mehrere Assemblys auf, damit Code separat bereitgestellt werden kann. Eine architektonische Schicht ist dagegen ein logisches Artefakt. Es ist sehr gut möglich (und üblich), mehrere Schichten in derselben Baugruppe zu haben.
In diesem Fall befinden sich der Composition Root (Layer) und der Presentation Layer im selben Webanwendungsprojekt (also in derselben Assembly). Und obwohl diese Versammlung verweist auf die Baugruppe die DAL enthält, das Presentation - Layer noch verweist nicht auf die Datenzugriffsschicht . Dies ist ein großer Unterschied.
Wenn wir dies tun, verlieren wir natürlich die Fähigkeit des Compilers, diese Architekturregel beim Kompilieren zu überprüfen, aber dies sollte kein Problem sein. Die meisten Architekturregeln können vom Compiler nicht überprüft werden, und es gibt immer so etwas wie gesunden Menschenverstand. Und wenn es in Ihrem Team keinen gesunden Menschenverstand gibt, können Sie immer Codeüberprüfungen verwenden (was IMO übrigens jedes Team immer tun sollte). Sie können auch ein Tool wie NDepend (kommerziell) verwenden, mit dem Sie Ihre Architekturregeln überprüfen können. Wenn Sie NDepend in Ihren Erstellungsprozess integrieren, kann es Sie warnen, wenn jemand Code eingecheckt hat, der gegen eine solche Architekturregel verstößt.
Eine ausführlichere Diskussion über die Funktionsweise der Kompositionswurzel finden Sie in Kapitel 4 meines Buches Abhängigkeitsinjektion, Prinzipien, Praktiken, Muster .
quelle
Sie können ein separates Projekt mit dem Namen "DependencyResolver" erstellen. In diesem Projekt müssen Sie alle Ihre Bibliotheken referenzieren.
Jetzt benötigt die UI-Ebene kein NHibernate / EF oder eine andere nicht UI-relevante Bibliothek außer Castle Windsor, auf die verwiesen werden soll.
Wenn Sie Castle Windsor und DependencyResolver von Ihrer UI-Ebene ausblenden möchten, können Sie ein HttpModule schreiben, das das IoC-Registrierungsmaterial aufruft.
Ich habe nur ein Beispiel für StructureMap:
Die DefaultControllerFactory verwendet den IoC-Container nicht direkt, sondern delegiert an IoC-Containermethoden.
Der
GetController
Delegat wird in einer StructureMap-Registrierung festgelegt (in Windsor sollte es sich um ein Installationsprogramm handeln).quelle
quelle