3581 Stimmen

Was ist Dependency Injection?

Es wurden bereits mehrere Fragen zu folgenden Themen gestellt Dependency Injection wie z. B. wann sie zu verwenden ist und welche Rahmenbedingungen es dafür gibt. Wie auch immer,

Was ist Dependency Injection und wann und warum sollte sie eingesetzt werden?

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.

197voto

user2771704 Punkte 5544

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.

4 Stimmen

Nur aus Neugier, wie unterscheidet sich dies von Strategie-Muster? Dieses Muster kapselt die Algorithmen und macht sie austauschbar. Ich habe das Gefühl, dass Dependency Injection und Strategiemuster sehr ähnlich sind.

0 Stimmen

Das ist eine großartige Antwort.

118voto

Pmpr.ir Punkte 16005

Diese ist die einfachste Erklärung über Injektion von Abhängigkeiten y Dependency Injection Container die ich je gesehen habe:

Ohne Dependency Injection

  • Anwendung braucht Foo (z.B. einen Controller), also:
  • Anwendung erstellt Foo
  • Anwendung ruft Foo auf
    • Foo braucht Bar (z.B. eine Dienstleistung), also:
    • Foo schafft Bar
    • Foo ruft Bar
      • Bar braucht Bim (einen Dienst, ein Repository, ), also:
      • Bar schafft Bim
      • Bar macht etwas

Mit Dependency Injection

  • Die Anwendung braucht Foo, diese braucht Bar, diese braucht Bim, also:
  • Anwendung erstellt Bim
  • Anwendung erstellt Bar und gibt ihr Bim
  • Anwendung erstellt Foo und gibt ihm Bar
  • Anwendung ruft Foo auf
    • Foo ruft Bar
      • Bar macht etwas

Verwendung eines Dependency Injection Containers

  • Anwendung braucht Foo so:
  • Die Anwendung erhält Foo vom Container, also:
    • Container schafft Bim
    • Container erstellt Bar und gibt ihr Bim
    • Container erstellt Foo und gibt ihm Bar
  • Anwendung ruft Foo auf
    • Foo ruft Bar
      • Bar macht etwas

Injektion von Abhängigkeiten y Abhängigkeit Injektionscontainer sind unterschiedliche Dinge:

  • Dependency Injection ist eine Methode zum Schreiben von besserem Code
  • ein DI-Container ist ein Werkzeug, das beim Einfügen von Abhängigkeiten hilft

Sie brauchen keinen Container, um Dependency Injection zu betreiben. Ein Container kann Ihnen jedoch helfen.

101voto

Gk Mohammad Emon Punkte 4144

Bevor wir uns der technischen Beschreibung zuwenden, sollten wir sie zunächst anhand eines Beispiels aus dem wirklichen Leben veranschaulichen, denn es gibt eine Menge technisches Material zum Erlernen von Dependency Injection, aber die meisten Menschen können das Kernkonzept nicht verstehen.

Im ersten Bild nehmen Sie an, dass Sie eine Autofabrik mit einer Vielzahl von Einheiten. Ein Auto wird eigentlich in der Montageeinheit aber es braucht Motor , Sitze wie auch Räder . Also ein Montageeinheit ist von diesen Einheiten abhängig und sie sind die Abhängigkeiten der Fabrik.

Sie haben das Gefühl, dass es jetzt zu kompliziert ist, alle Aufgaben in dieser Fabrik zu erledigen, weil Sie sich neben der Hauptaufgabe (Zusammenbau eines Autos in der Montageeinheit) auch auf Folgendes konzentrieren müssen andere Einheiten . Die Instandhaltung ist jetzt sehr kostspielig, und das Fabrikgebäude ist riesig, so dass Sie mehr Geld für die Miete ausgeben müssen.

Sehen Sie sich nun das zweite Bild an. Wenn Sie einige Anbieterfirmen finden, die Ihnen die Rad , Sitz y Motor billiger als Ihre eigenen Produktionskosten, dann brauchen Sie sie nicht mehr in Ihrer Fabrik herzustellen. Sie können jetzt ein kleineres Gebäude mieten, nur für Ihre Montageeinheit Dies verringert Ihre Wartungsarbeiten und reduziert Ihre zusätzlichen Mietkosten. Jetzt können Sie sich auch nur auf Ihre Hauptaufgabe (Fahrzeugmontage) konzentrieren.

Jetzt können wir sagen, dass alle Abhängigkeiten für den Zusammenbau eines Autos sind eingespritzt in der Fabrik aus dem Anbieter . Es ist ein Beispiel für ein reales Leben Dependency Injection (DI) .

In der Fachsprache ist Dependency Injection eine Technik, bei der ein Objekt (oder eine statische Methode) die Abhängigkeiten eines anderen Objekts bereitstellt. Die Übertragung der Aufgabe, das Objekt zu erstellen, auf ein anderes und die direkte Nutzung der Abhängigkeit wird als Dependency Injection bezeichnet.

Diese wird Ihnen jetzt helfen, DI mit einer technischen Erklärung zu lernen. Diese wird zeigen, wann Sie DI verwenden und wann Sie no .

All in one car factory .

Simple car factory

5 Stimmen

Hut ab vor der visuellen Darstellung des Konzepts!

69voto

JaneGoodall Punkte 1388

Bedeutet "Dependency Injection" nicht einfach die Verwendung parametrisierter Konstruktoren und öffentlicher Setter?

In dem Artikel von James Shore werden folgende Beispiele zum Vergleich angeführt .

Konstrukteur ohne Dependency Injection:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
} 

Konstrukteur mit Dependency Injection:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
}

0 Stimmen

Sicherlich in der DI-Version würden Sie nicht wollen, um die myDatabase Objekt in der kein Argument Konstruktor initialisieren? Es scheint keinen Sinn zu machen und würde eine Ausnahme auslösen, wenn Sie versuchen, DoStuff aufzurufen, ohne den überladenen Konstruktor aufzurufen?

0 Stimmen

Nur wenn new DatabaseThingie() erzeugt keine gültige myDatabase-Instanz.

47voto

wakqasahmed Punkte 2019

Um das Konzept der Dependency Injection einfach zu verstehen. Nehmen wir ein Beispiel eines Schalters, der eine Glühbirne ein- und ausschaltet.

Ohne Dependency Injection

Der Schalter muss vorher wissen, an welche Glühbirne ich angeschlossen bin (fest kodierte Abhängigkeit). Also,

Schalter -> Dauerbirne //Schalter ist direkt mit Glühbirne verbunden, Prüfung nicht ohne weiteres möglich

Switch(){
PermanentBulb = new Bulb();
PermanentBulb.Toggle();
}

Mit Dependency Injection

Der Schalter weiß nur, dass ich die Glühbirne ein- und ausschalten muss, die an mich weitergegeben wird. Also,

Schalter -> Glühbirne1 OR Glühbirne2 OR Nachtbirne (injizierte Abhängigkeit)

Switch(AnyBulb){ //pass it whichever bulb you like
AnyBulb.Toggle();
}

Ändern von James Beispiel für Schalter und Glühbirne:

public class SwitchTest { 
  TestToggleBulb() { 
    MockBulb mockbulb = new MockBulb(); 

    // MockBulb is a subclass of Bulb, so we can 
    // "inject" it here: 
    Switch switch = new Switch(mockBulb); 

    switch.ToggleBulb(); 
    mockBulb.AssertToggleWasCalled(); 
  } 
}

public class Switch { 
  private Bulb myBulb; 

  public Switch() { 
    myBulb = new Bulb(); 
  } 

  public Switch(Bulb useThisBulbInstead) { 
    myBulb = useThisBulbInstead; 
  } 

  public void ToggleBulb() { 
    ... 
    myBulb.Toggle(); 
    ... 
  } 
}`

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X