Laravel 5 - Method Injection

Ein kleines aber sehr cooles meiner Lieblings-Features ist Method Injection.

Bisher konnten wir andere Klassen durch Constructor Injection laden oder Instanzen einfach via App::make() erstellen. Generell heißt diese Methode Dependency Injection.

Constructor Injection

Wird eine fremde Klasse in mehreren Methoden der aktuellen Klasse benötigt bietet sich die Constructor Injection an. Man kann eine Klasse einfach via type-hint im Constructor laden. Als Beispiel:

// ProductsController.php

class ProductsController extends Controller {

    protected $paymentMethod;

   function __construct(PaymentMethod $paymentMethod) {
        $this->paymentMethod = $paymentMethod;
   }

   function checkout() {
        // Get all paymentMethods
        $paymentMethods = $this->paymentMethods->getActivePaymentMethods();
   }
}

In jeder Methode dieser Klasse hat man nun Zugriff auf $this->paymentMethod.

Method Injection

Dasselbe können wir nun auch bei Methoden machen. Das ist besonders praktisch wenn wir die andere Klasse nur in einer Methode benötigen. Als Beispiel:

// ProductsController.php

class ProductsController extends Controller {

   function index(FilterValidator $filterValidator, Request $request) {
        $stats = $filterValidator->validate($request->all());
   }
}

Hier benötige ich eine Klasse FilterValidator die mir eingestellte Filterung meiner Produkübersichtsseite überprüft. z.B. soll bei der Preisspanne nicht mehr als 200€ angegeben werden, das möchte ich validieren. In allen anderen Methoden ist dieser FilterValidator nutzlos. In Zukunft kann ich diesen über die Method Injection verfügbar machen und spare mir das App::make() (was aber auch noch funktionieren würde).

Warum überhaupt Depenency Injection

Möchte ich meine Klasse test-freundlich gestalten, verwende ich Dependency Injection. Dadurch lassen sich beim Testen anstatt der echten Klasse so etwas wie Dummy-Klassen (Mocks) laden. Der Test kann sich somit nur auf die aktuelle Klasse beschränken. Die nachgeladene Klasse sollte sowieso seine eigenen Tests mitbringen, daher reicht auch das laden des Mocks.