Dependency Injection (DI) ist ein Entwurfsmuster, bei dem ein Objekt seine Abhaengigkeiten nicht selbst erzeugt, sondern von aussen uebergeben bekommt. Eine Klasse, die eine Datenbank benoetigt, ruft also nicht selbst den Konstruktor der Datenbankklasse auf, sondern erhaelt die fertige Instanz als Parameter. Das entkoppelt Objekte und macht sie einzeln testbar.
Die drei Formen
- Constructor Injection: Die Abhaengigkeit wird ueber den Konstruktor der Klasse uebergeben — die haeufigste Variante.
- Setter Injection: Die Abhaengigkeit wird nach der Erzeugung ueber eine Setter-Methode gesetzt.
- Interface Injection: Das Objekt implementiert ein Interface, ueber das die Abhaengigkeit injiziert wird.
Vorteile
- Testbarkeit: In Unit-Tests lassen sich echte Abhaengigkeiten durch Test-Doubles ersetzen, weil die Klasse nur das Interface kennt.
- Lose Kopplung: Die Klasse haengt an Abstraktionen statt an konkreten Implementierungen.
- Austauschbarkeit: Datenbanken, Dienste oder Konfigurationen koennen gewechselt werden, ohne die Klasse zu aendern.
DI-Container
Grosse Frameworks automatisieren die Verdrahtung mit einem DI-Container. Das Framework registriert, welche Implementierung zu welchem Interface gehoert, und baut den Objektgraphen automatisch auf. Bekannte Beispiele sind Spring (Java), Angular (TypeScript), Laravel (PHP) und ASP.NET Core (C#).
DI ist eng verwandt mit dem Prinzip der Inversion of Control: Nicht das Objekt bestimmt, welche Abhaengigkeit es nutzt, sondern die Umgebung. Dadurch bleibt der Code modular und die einzelnen Bausteine unabhaengig voneinander entwickel- und testbar.