2014-11-22 15 views
6

Was war ich nur den Konstruktor und Verwendung Fassaden für die Laravel der bereitgestellten Klassen meiner Modelle zu inject zuvor getan hatte heißen Session, Auth, Validator etc, zum Beispiel unter Verwendung. Wird es eine gute Idee, wenn ich jede Klasse (entweder meine oder Laravel) durch Konstrukt injizieren und es durch $this->.. Syntax oder sollte ich meine eigenen Klassen mit Konstruktor injizieren und Fassaden für alles von Laravel bereitgestellten verwenden?Laravel: Abhängigkeitsinjektion vs Fassaden?

Genauer gesagt, hier ist das, was normalerweise meine Controller wie folgt aussehen:

class MyController extends BaseController 
{ 
    public function __construct(User $user, Bookmark $bookmark) { 
     $this->user = $user; 
     $this->bookmark = $bookmark 
    } 

    public function foobar () { 
     $user_id = Input::get('bar'); 
     ... 
     Session::get('someInfo'); 
     ... 
     return Redirect::to('/'); 
    } 
    ... 
} 

möchte ich nach meiner Methoden wie Controller strukturieren, statt?

class MyController extends BaseController 
{ 
    public function __construct(User $user, Bookmark $bookmark, Input $input, Session $session, Redirect $redirect) { 
     $this->user = $user; 
     $this->bookmark = $bookmark 
     $this->input = $input; 
     $this->session = $session; 
     $this->redirect = $redirect; 
    } 

    public function foobar () { 
     $user_id = $this->input->get('bar'); 
     ... 
     $this->session->get('someInfo'); 
     ... 
     return $this->redirect->to('/'); 
    } 
    ... 
} 
+0

Diese Frage scheint off-topic zu sein, weil sie auf programmers.stackexchange.com sein sollte –

+0

Wissen Sie * warum * Sie sollten Objekte anstelle von Laravels Fassaden injizieren? –

+3

@FlorianMargaine, sollte * "Fassaden" * sein. –

Antwort

1

Laravel unterstützt nun die gleiche Funktionalität für Injektions Methoden der Klassen (und nicht nur Konstruktoren) die routenbezogenen sind, wie Controller und Middleware.

Sie unnötige Injektionen verhindern könnten nur auf Verfahren injizieren, wo die Abhängigkeit eindeutig zuzuordnen sind, vielleicht häufiger Abhängigkeiten im Konstruktor verlassen:

class MyController extends BaseController 
{ 
    public function __construct(Input $input, Session $session, Redirect $redirect) { 
     $this->input = $input; 
     $this->session = $session; 
     $this->redirect = $redirect; 
    } 

    public function foobar (User $user, Bookmark $bookmark) { 
     $user_id = $this->input->get('bar'); 
     ... 
     $this->session->get('someInfo'); 
     ... 
     return $this->redirect->to('/'); 
    } 
    ... 
} 

Als ob Sie es auf diese Weise tun sollten, ist, dass bei Ihnen - Das Erzwingen, dass alle Abhängigkeiten in den Methodendefinitionen erscheinen, erscheint mir sauberer und einfacher zu testen.

0

Es ist elegant und nützlich, bestimmte Klassen wie Request zu injizieren. Meiner Meinung nach sollten sie in Controller-Methoden spezifiziert werden, wo sie benötigt werden, da sie dann logisch mit der Methodenimplementierung verbunden sind. Super bis jetzt.

Ich finde zwei Fassaden problematisch - App und Log. Beide sind nicht logisch mit einem Controller oder seinen Aktionen verbunden. App und Log sind keine Eingaben in irgendeinem Zusammenhang. Da App und Log Utility-Klassen sind, sind sie auch für Services und Repositories relevant, und es wird geradezu fies, wenn Sie sie in Controller eingeben und sie dann als Konstruktor- oder Methodenparameter an Ihre Support-Klassen weitergeben.

Ein weiteres Problem ist, dass die App-Fassade nicht die Illuminate \ Contracts \ Auth \ Guard-Schnittstelle implementiert, die sie proxies, so dass meine IDE mit Warnungen aufleuchtet, da statische Analyse nicht möglich ist.

Aus Gründen der Konsistenz und allgemeinen Trennung von Bedenken würde ich daher sowohl App als auch Log in einem Konstruktor oder einer Methode instanziieren, je nachdem, wie weit sie in einer Klasse verwendet werden. Zu meinen IDE glücklich macht mir die folgende Klasse erstellt, um mir eine richtig getippt Instanz, wo immer ich sie brauche:

<?php namespace App\Components; 

use Illuminate\Contracts\Auth\Guard; 
use Psr\Log\LoggerInterface; 

/** 
* Get the underlying object instances of facades from the container. 
*/ 
class AppGlobal 
{ 
    /** 
    * Returns the global logger instance. 
    * 
    * @return LoggerInterface 
    */ 
    public static function log() 
    { 
     return app('log'); 
    } 

    /** 
    * Returns the global auth instance, which internally proxies a guard. 
    * 
    * @return Guard 
    */ 
    public static function auth() 
    { 
     return app('auth'); 
    } 

} 
+0

In diesen Tagen gehen die Leute extra viel, um ihre Software glücklich zu machen ... –

0

Wenn Sie ein Objekt wit Eigenschaften müssen - setze sie in als Injektion (zB Input, Session .. .), ansonsten, wenn du keine Daten im Objekt speicherst und mit der Klasse schön glücklich bist, dann geh mit Fassaden (zB Log :: ..., Redirect :: ...).

0

Laravel hat

use Auth; 

und

Auth::user() 

ist jetzt nur

auth()->user() 

diese Sache einfacher und übersichtlicher macht (auch Fehler viele seiner Fassade mit Helfer zum Beispiel ersetzt verhindert)

Ich würde vorschlagen, die Helfer zu verwenden, wo es möglich ist, und wenn kein Helfer vorhanden ist, benutze die Fassade, weil es leichter ist, sich zu verstellen als eine injizierte Instanz.

+1

Die Verwendung beider beschriebenen Methoden erzeugt eine unnötige Abhängigkeit in den Code/Tests und beruht auf Laravels Magie, um die statische aufzulösen Auth :: Anruf. Second verwendet erneut einen globalen Funktionsaufruf, um eine Abhängigkeit zu erstellen. Besser, die Abhängigkeit im Konstruktor zu initialisieren und diese zu verwenden. – Nick

Verwandte Themen