Injektion von Abhängigkeiten
Anstatt die Teile selbst zu instanziieren, wird ein Auto fragt für die Teile, die es zum Funktionieren braucht.
class Car
{
private Engine engine;
private SteeringWheel wheel;
private Tires tires;
public Car(Engine engine, SteeringWheel wheel, Tires tires)
{
this.engine = engine;
this.wheel = wheel;
this.tires = tires;
}
}
Fabrik
Fügt die Teile zu einem vollständigen Objekt zusammen und verbirgt den konkreten Typ vor dem Aufrufer.
static class CarFactory
{
public ICar BuildCar()
{
Engine engine = new Engine();
SteeringWheel steeringWheel = new SteeringWheel();
Tires tires = new Tires();
ICar car = new RaceCar(engine, steeringWheel, tires);
return car;
}
}
Ergebnis
Wie Sie sehen können, ergänzen sich Fabriken und DI.
static void Main()
{
ICar car = CarFactory.BuildCar();
// use car
}
Erinnerst du dich an Goldlöckchen und die drei Bären? Nun, mit der Dependency Injection ist es so eine Sache. Hier sind drei Möglichkeiten, das Gleiche zu tun.
void RaceCar() // example #1
{
ICar car = CarFactory.BuildCar();
car.Race();
}
void RaceCar(ICarFactory carFactory) // example #2
{
ICar car = carFactory.BuildCar();
car.Race();
}
void RaceCar(ICar car) // example #3
{
car.Race();
}
Beispiel 1 - Das ist das Schlimmste, weil es die Abhängigkeit völlig verdeckt. Wenn Sie die Methode als Blackbox betrachten würden, wüssten Sie nicht, dass sie ein Auto benötigt.
Beispiel #2 - Das ist schon etwas besser, denn jetzt wissen wir, dass wir ein Auto brauchen, da wir in einer Autofabrik vorbeikommen. Aber dieses Mal übergeben wir zu viel, denn alles, was die Methode wirklich braucht, ist ein Auto. Wir übergeben eine Fabrik, nur um das Auto zu bauen, wenn das Auto auch außerhalb der Methode gebaut und übergeben werden könnte.
Beispiel #3 - Dies ist ideal, da die Methode folgende Fragen stellt genau was es braucht. Nicht zu viel und nicht zu wenig. Ich muss keine MockCarFactory schreiben, nur um MockCars zu erstellen, ich kann den Mock direkt übergeben. Es ist direkt und die Schnittstelle lügt nicht.
Dieser Google Tech Talk von Misko Hevery ist erstaunlich und bildet die Grundlage für mein Beispiel. http://www.youtube.com/watch?v=XcT4yYu_TTs
27 Stimmen
Können sich diese beiden Ansätze nicht gegenseitig ergänzen, indem man Dependency Injection zur Injektion von Fabrikklassen verwendet?
21 Stimmen
Es wäre wirklich schön, wenn diese Frage mit einem Code beantwortet werden könnte! Ich sehe immer noch nicht, wie DI vorteilhaft/unterschiedlich von der Verwendung einer Fabrik für die Erstellung sein würde? Sie müssen nur diese eine Zeile in der Fabrikklasse ersetzen, um zu ändern, welches Objekt/Implementierung erstellt wird?
2 Stimmen
@gideon würde das nicht dazu führen, dass Sie Ihre Anwendung kompilieren müssen, oder zumindest das Modul, das die Fabrikklasse enthält?
1 Stimmen
@liortal Ja, das ist richtig. Habe eine lange Studie über DI seit diesem Kommentar und jetzt verstehe ich die DI nimmt die Fabrik-Methode einen Schritt voraus.
1 Stimmen
Sehen Sie sich diese großartige Antwort an: stackoverflow.com/questions/4985455/ - er formuliert es sehr gut und liefert Codebeispiele.
0 Stimmen
Haben Sie jemals eine Anwendung von Dependency Injection gesehen, die keine Factories verwendet hat? Das wäre seltsam, da Dependency Injection bedeutet, dass der Code zur Erstellung eines Objekts an einer einzigen Stelle platziert wird, was die gesamte Komplexität/Abstraktion/den ganzen Overhead einer Factory mit sich bringt. Wäre es nicht dumm, DI zu verwenden, aber keine Fabriken?
0 Stimmen
Falls jemand daran interessiert ist, wie Dependency Injection in einem Coffeeshop-Theme hilfreich sein kann, habe ich hier einen Artikel darüber geschrieben: digigene.com/design-patterns/dependency-injection-coffeeshop
0 Stimmen
Die Antwort mit den meisten Stimmen macht keinen Sinn. Das Factory Design Pattern verwendet das Prinzip der Abhängigkeitsinversion, das die Instanziierung des Codes in eine andere Klasse auslagert, daher macht seine Antwort keinen Sinn.
0 Stimmen
Um eine gute Dependency Injection zu machen, müssen Sie sich auf Factories verlassen, die es Ihnen erlauben, eine Composition Root zu machen, eine obere Schicht, die alle Ihre entkoppelten Komponenten zusammen verdrahtet, die zu Ihrem Implementierungsfall passen, Sie können einen Blick auf die Di-Ninja Bibliothek werfen, dies ist ein gutes Beispiel für Quellcode, um die Ziele der Dependency Injection zu erklären github.com/di-ninja/di-ninja