Jedes Mal, wenn mich jemand erreicht und mich bittet, die Abhängigkeitsinjektion konzeptionell zu definieren und die tatsächlichen Vor- und Nachteile der Verwendung von DI im Software-Design zu erläutern. Ich gebe zu, dass ich einige Schwierigkeiten habe, die Konzepte von DI zu erklären. Jedes Mal, wenn ich ihnen die Geschichte über das Prinzip der Einzelverantwortung, die Zusammensetzung über die Vererbung usw. erzählen muss.
Kann mir jemand helfen, die beste Art zu erklären, DI für Entwickler zu beschreiben?
design
design-patterns
software
Tiago Sampaio
quelle
quelle
Antworten:
Dependency Injection ist ein schrecklicher Name (IMO) 1 für ein recht einfaches Konzept. Hier ist ein Beispiel:
DbContext
. B. a ). Diese interne Ressource wird als Abhängigkeit bezeichnetDbContext
) aus der Methode und machen es zur Verantwortung des Aufrufers, diese Ressource bereitzustellen (als Methodenparameter oder nach Instanziierung der Klasse).[1] : Ich komme aus einer niedrigeren Ebene und habe Monate gebraucht, um mich hinzusetzen und die Abhängigkeitsinjektion zu lernen, da der Name impliziert, dass es viel komplizierter wäre, wie DLL-Injektion . Die Tatsache, dass Visual Studio (und wir Entwickler im Allgemeinen) auf die .NET-Bibliotheken (DLLs oder Assemblys ) verweist, von denen ein Projekt als Abhängigkeiten abhängt, hilft überhaupt nicht. Es gibt sogar so etwas wie den Dependency Walker (abhängige.exe) .
[Bearbeiten] Ich dachte, ein Demo-Code würde für einige nützlich sein, also hier ist einer (in C #).
Ohne Abhängigkeitsinjektion:
Ihr Verbraucher würde dann so etwas tun:
Dieselbe Klasse, die mit einem Abhängigkeitsinjektionsmuster implementiert wurde, würde folgendermaßen aussehen:
Es liegt nun in der Verantwortung des Anrufers, a zu instanziieren
DbContext
und an Ihre Klasse weiterzuleiten (errm, injizieren ):quelle
Abstrakte Konzepte lassen sich oft besser anhand einer realen Analogie erklären. Dies ist meine Analogie:
Es ist nicht perfekt, aber es unterstreicht das Hauptmerkmal: dem Verbraucher die Kontrolle zu geben . Die inhärente Win-Win-Situation besteht darin, dass Sie keine eigenen Abhängigkeiten mehr erwerben müssen und Ihr Verbraucher bei der Auswahl der Abhängigkeit ungehindert ist.
quelle
Einfache Antwort darauf:
.Net Core ist ein ziemlich gutes Beispiel, das Sie geben können, da dieses Framework viel Abhängigkeitsinjektion verwendet. Im Allgemeinen befinden sich die Dienste, die Sie injizieren möchten, in der
startup.cs
Datei.Sicher, der Schüler sollte einige Konzepte wie Polymorphismus, Schnittstellen und OOP-Design-Prinzipien kennen.
quelle
Es gibt viel Flaum und Bunker um das, was im Wesentlichen ein einfaches Konzept ist.
Es ist auch sehr leicht, sich mit " Welches Framework sollte ich verwenden " festzumachen, wenn Sie es ganz einfach in Code tun können.
Dies ist die Definition, die ich persönlich verwende:
Einige Beispiele könnten sein, wenn Y ein Dateisystem oder eine Datenbankverbindung ist.
Frameworks wie moq ermöglichen die Definition von Doubles ( Pretend- Versionen von Y) über eine Schnittstelle, sodass eine Instanz von Y eingefügt werden kann , wobei Y beispielsweise eine Datenbankverbindung ist.
Es ist leicht, in die Falle zu tappen, zu glauben, dass dies nur ein Unit-Testing-Problem ist, aber es ist ein sehr nützliches Muster für jeden Code, bei dem Änderungen erwartet werden, und es ist wahrscheinlich trotzdem eine gute Praxis.
quelle
Wir stellen das Verhalten einer Funktion zur Laufzeit durch die Methode zum Einfügen dieses Verhaltens in die Funktion über einen Parameter bereit.
Das Strategiemuster ist ein hervorragendes Beispiel für die Abhängigkeitsinjektion.
quelle
Um dies richtig zu machen, müssen wir zuerst Abhängigkeiten und Injektionen definieren.
Ein rudimentäres Beispiel wäre eine Methode, die zwei Werte hinzufügt. Offensichtlich müssen bei dieser Methode die Werte hinzugefügt werden. Wenn sie durch Übergabe als Argumente bereitgestellt werden, handelt es sich bereits um eine Abhängigkeitsinjektion. Die Alternative wäre, die Operanden als Eigenschaften oder globale Variablen zu implementieren. Auf diese Weise würden keine Abhängigkeiten eingefügt, die Abhängigkeiten wären im Voraus extern verfügbar.
Angenommen, Sie verwenden stattdessen Eigenschaften und benennen sie A und B. Wenn Sie die Namen in Op1 und Op2 ändern, wird die Add-Methode unterbrochen. Oder Ihre IDE würde alle Namen für Sie aktualisieren. Der Punkt ist, dass die Methode ebenfalls aktualisiert werden muss, da sie von externen Ressourcen abhängig ist.
Dieses Beispiel ist einfach, aber Sie können sich komplexere Beispiele vorstellen, bei denen die Methode eine Operation an einem Objekt wie einem Bild ausführt oder aus einem Dateistream liest. Möchten Sie, dass die Methode nach dem Bild greift und wissen muss, wo es sich befindet? Nein. Möchten Sie, dass die Methode die Datei selbst öffnet und weiß, wo sie nach der Datei suchen muss oder ob sie aus einer Datei liest? Nein.
Der Punkt: Die Funktionalität einer Methode auf ihr Kernverhalten reduzieren und die Methode von ihrer Umgebung entkoppeln. Sie erhalten das erste, indem Sie das zweite ausführen. Sie können dies als Definition der Abhängigkeitsinjektion betrachten.
Die Vorteile: Da Abhängigkeiten für die Umgebung der Methode beseitigt wurden, wirken sich Änderungen an der Methode nicht auf die Umgebung aus und umgekehrt. => Die Anwendung wird einfacher zu warten (zu ändern).
quelle