Versuchen wir ein einfaches Beispiel mit Auto y Motor Klassen, jedes Auto braucht einen Motor, um irgendwo hinzufahren, zumindest im Moment. Unten sehen Sie, wie der Code ohne Dependency Injection aussehen wird.
public class Car
{
public Car()
{
GasEngine engine = new GasEngine();
engine.Start();
}
}
public class GasEngine
{
public void Start()
{
Console.WriteLine("I use gas as my fuel!");
}
}
Und um die Klasse Car zu instanziieren, verwenden wir den folgenden Code:
Car car = new Car();
Das Problem bei diesem Code ist, dass wir eng an die GasEngine gekoppelt sind, und wenn wir uns entscheiden, sie in die ElectricityEngine zu ändern, müssen wir die Klasse Car neu schreiben. Und je größer die Anwendung ist, desto mehr Probleme und Kopfschmerzen werden wir haben, um neue Arten von Motoren hinzuzufügen und zu verwenden.
Mit anderen Worten bedeutet dieser Ansatz, dass unsere Klasse Car auf hoher Ebene von der Klasse GasEngine auf niedrigerer Ebene abhängig ist, was gegen das Dependency Inversion Principle (DIP) von SOLID verstößt. DIP legt nahe, dass wir von Abstraktionen und nicht von konkreten Klassen abhängig sein sollten. Um dies zu erfüllen, führen wir die Schnittstelle IEngine ein und schreiben den Code wie folgt um:
public interface IEngine
{
void Start();
}
public class GasEngine : IEngine
{
public void Start()
{
Console.WriteLine("I use gas as my fuel!");
}
}
public class ElectricityEngine : IEngine
{
public void Start()
{
Console.WriteLine("I am electrocar");
}
}
public class Car
{
private readonly IEngine _engine;
public Car(IEngine engine)
{
_engine = engine;
}
public void Run()
{
_engine.Start();
}
}
Jetzt ist unsere Car-Klasse nur noch von der IEngine-Schnittstelle abhängig, nicht mehr von einer bestimmten Implementierung der Engine. Der einzige Trick besteht nun darin, eine Instanz von Car zu erzeugen und ihr eine konkrete Engine-Klasse wie GasEngine oder ElectricityEngine zu geben. Das ist der Punkt, an dem Injektion von Abhängigkeiten kommt herein.
Car gasCar = new Car(new GasEngine());
gasCar.Run();
Car electroCar = new Car(new ElectricityEngine());
electroCar.Run();
Hier injizieren (übergeben) wir im Grunde unsere Abhängigkeit (Engine-Instanz) an den Car-Konstruktor. Jetzt haben unsere Klassen also eine lose Kopplung zwischen Objekten und ihren Abhängigkeiten, und wir können leicht neue Motorentypen hinzufügen, ohne die Car-Klasse zu ändern.
Der Hauptnutzen des Injektion von Abhängigkeiten dass Klassen lockerer gekoppelt sind, weil sie keine fest kodierten Abhängigkeiten haben. Dies entspricht dem oben erwähnten Prinzip der Inversion von Abhängigkeiten. Anstatt auf bestimmte Implementierungen zu verweisen, fordern Klassen Abstraktionen an (in der Regel Schnittstellen ), die ihnen bei der Konstruktion der Klasse zur Verfügung gestellt werden.
Am Ende also Injektion von Abhängigkeiten ist nur eine Technik für lose Kopplung zwischen Objekten und ihren Abhängigkeiten zu erreichen. Anstatt direkt Abhängigkeiten zu instanziieren, die die Klasse benötigt, um um ihre Aktionen auszuführen, werden die Abhängigkeiten der Klasse bereitgestellt (meistens) über Konstruktorinjektion.
Auch wenn wir viele Abhängigkeiten haben, ist es eine sehr gute Praxis, Inversion of Control(IoC)-Container zu verwenden, in denen wir angeben können, welche Schnittstellen auf welche konkreten Implementierungen für alle unsere Abhängigkeiten abgebildet werden sollen, und wir können diese Abhängigkeiten für uns auflösen lassen, wenn es unser Objekt konstruiert. Zum Beispiel könnten wir in der Abbildung für den IoC-Container angeben, dass die IEngine Abhängigkeit sollte auf die GasEngine Klasse und wenn wir den IoC-Container um eine Instanz unserer Auto Klasse, konstruiert es automatisch unsere Auto Klasse mit einer GasEngine Abhängigkeit übergeben.
UPDATE : Ich habe mir kürzlich den Kurs über EF Core von Julie Lerman angesehen und fand auch ihre kurze Definition über DI gut.
Dependency Injection ist ein Muster, das es Ihrer Anwendung ermöglicht, Objekte Klassen, die sie benötigen, zu injizieren, ohne diese Klassen zu zwingen Klassen zu zwingen, für diese Objekte verantwortlich zu sein. Es ermöglicht Ihrem Code zu sein lockerer gekoppelt werden, und Entity Framework Core fügt sich in dieses System von Diensten.
0 Stimmen
Siehe meine Diskussion über Dependency Injection Hier .
44 Stimmen
Ich stimme den Kommentaren zu den Links zu. Ich kann verstehen, dass Sie vielleicht auf jemand anderen verweisen wollen. Aber fügen Sie zumindest hinzu, warum Sie sie verlinken und was diesen Link besser macht als die anderen Links, die ich mit Google finden könnte
0 Stimmen
@AR: Technisch gesehen, ist Dependency Injection no eine besondere Form von IoC. Vielmehr ist IoC eine Technik, die zur Bereitstellung von Dependency Injection verwendet wird. Es können auch andere Techniken für die Dependency Injection verwendet werden (obwohl IoC die einzige ist, die häufig verwendet wird), und IoC wird auch für viele andere Probleme verwendet.
157 Stimmen
Was die Links betrifft, so ist zu bedenken, dass sie oft auf die eine oder andere Weise verschwinden. Die Zahl der toten Links in SO-Antworten steigt. Egal, wie gut der verlinkte Artikel ist, er nützt nichts, wenn man ihn nicht finden kann.
0 Stimmen
Vojta Jina über Dependency Injection youtu.be/_OGGsf1ZXMs . Der erste Teil.
0 Stimmen
Ein Überblick über Dependency Injection und ihre Beziehung zu anderen OOP-Prinzipien: deviq.com/dependency-injection
0 Stimmen
Hier ist ein Anwendungsbeispiel ohne DI: tugay.biz/2017/05/standalone-jpa-beispiel-mit-hibernate.html und dasselbe mit DI: tugay.biz/2017/05/add-c3p0-to-previous-example.html