Dependency Injection
Unter Dependeny Injection verstehen wir den Vorgang des Verbindens eines Objekts mit anderen Objekten, indem Abhängigkeiten in Form von Referenzen in dieses von außen injiziert, also reingegeben werden. Diese Abhängigkeiten werden im Allgemeinen zur Laufzeit angebunden (spätes Binden). Im Standardfall hat dabei eine Klasse eine Abhängigkeit zu einer Schnittstelle, die dann zur Laufzeit an eine konkrete Implementierung gebunden wird.
Weitere Informationen befinden sich u.a. hier: http://martinfowler.com/articles/injection.html.
Design
Dependency Injection wird zum Aufbau der Struktur des Strategiemusters http://de.wikipedia.org/wiki/Strategie_(Entwurfsmuster) verwendet. Hierzu wird die Abhängigkeit von außen in das Objekt gegeben, also injiziert. Im Standardfall wird bei Schleupen dieses in den Konstruktor gegeben. Das wird als Constructor Injection bezeichnet
Die folgende Abbildung stellt die Abhängigkeitsbeziehung von A
auf IB
dar:
Die Abhängigkeit wird wie folgt aufgelöst:
In C# sieht das ganze wie folgt aus:
public class A { private readonly IB b; public Auto(IB b) { this.b = b; } } public interface IB { } public class B : IB { }
Die Dependency Injection zeigt sich dann zur Laufzeit - hier per frühem Binden gelöst:
IB b = new B(); // spätes Binden würde z.B. durch Konfiguration den konkreten Typ ermitteln und instanziieren A a = new(b);
Implementierung
Das Zusammenschalten der Objekte kann mit Hilfe eines sogenannten DI-Containers erfolgen. Diese sollte gemäß WCF-Integration erfolgen.
Das folgenden Beispiel demonstriert das Konzept noch einmal:
Gegeben sei ein Auto, das mit irgendeinem Motor bestückt werden soll:
In C# sieht das wie folgt aus:
public class Auto { private readonly IMotor motor; public Auto(IMotor motor) { this.motor = motor; } } public interface IMotor { void Starte(); } public class Motor : IMotor { public void Starte() { // ... } }
Abgrenzung
Dieses Muster klärt nicht, wie Domänenmodelle zusammengesetzt, das heißt instanziiert werden. Dieses Muster ist nur für Architekturkomponenten wie Service, Usecase Controller, (Assembler,) Repository zu verwenden.
Stärken und Schwächen
Stärken
- Fördert Schnittstellen-orientiertes Design
- Sorgt für lose Kopplung
- Die Software wird erweiterbar, testbar, parallel entwickelbar
Schwächen
- Loose Kopplung erhöht die Komplexität
- Missbrauch durch exzessive Nutzung möglich