Tutoriel Vidéo Laravel Dependency Injection, IoC Container & Facades

Télécharger la vidéo

Je vous propose aujourd'hui de découvrir Laravel en regardant ce qu'il a sous le capot.

En effet, il ne sera pas ici question de vous montrer comment utiliser le framework pour créer telle ou telle application mais plutôt de vous montrer 3 concepts utilisés par Laravel :

Ces 3 blocs constitue la base du fonctionnement de Laravel et comprend comment ils fonctionnent permet de comprendre la totalité du Framework (sa philosophie...). Comprendre le moteur est selon moi une chose essentielle pour aborder une nouvelle technologie.

L'injection de dépendance

Souvent, lorsque l'on conçoit une application PHP on se retrouve dans le cas ou un objet dépend d'un autre. Par exemple :

class Moteur{

    public function __construct(){
        $this->engine = new Engine(); 
    }

}

$moteur = new Moteur();

L'avantage de cette méthode c'est que la classe est facilement utilisable. En revanche la dépendance est liée à notre objet et il est impossible de remplacer Engine par une autre classe (pour des tests unitaires par exemple).

Une autre méthode consiste à "injecter" les dépendances dans le constructeur :

class Moteur{

    public function __construct($engine){
        $this->engine = $engine; 
    }

}

$engine = new Engine(); 
$moteur = new Moteur($engine);

Cette méthode d'injection est beaucoup plus modulable et personnalisable car on peut changer aisément la classe Engine par une autre implémentation (pour une version mocké par exemple pour les tests unitaires).

L'IOC Container

L'IOC Container est un outil qui permet de gérer et d'organiser les différentes dépendances.

Par exemple on peut définir un alias pour notre class Engine ;

App::bind('engine', function()
{
    return new Engine(); 
});

Ainsi on peut ensuite instancier la classe en faisant :

App::make('engine');

De même on peut utiliser ce système avec l'injection de dépendance :

App::bind('car', function()
{
    return new Car(App::make('engine')); 
});

L'avantage de cette méthode c'est que l'on peut modifier à la volée notre container pour modifier l'association :

App::bind('engine', function()
{
    return new ElectricEngine(); 
});

Ainsi cette nouvelle classe sera injectée dans toutes les classes qui dépendent d'engine.

Les différents binding peuvent être balancés à l'arrache (chose que je déconseille évidemment) ou on peut utiliser un ServiceProvider.

Toutes les classes utilisées dans Laravel utilisent cet IOC Container ainsi :

Route::get(...)

// Peut s'écrire 
App::make('router')->get(...)

// Ou encore
$app['router']->get(...)

Les Facades

Comment passe-t-on de App::make('router')->get(...) à Route::get(...) ? C'est là qu'un dernier élément rentre en jeu : Les Facades.

Les Facades permettent d'appeler l'IOC Container à travers une classe static.

namespace Grafikart\Facades;
use Illuminate\Support\Facades\Facade;

class Car extends Facade {

    protected static function getFacadeAccessor()       { 
        // On retourne ici l'alias de l'IOC Container
        return 'car'; 
    }

}

Ce qui me permet d'avoir une syntaxe static

Grafikart\Facades\Car::maMethode();

Si vous souhaitez simplifier cet appel sans utiliser le namespace vous pouvez définir un alias dans votre fichier config/app.php.

"aliases" => array(
    ...
    "Car" => "Grafikart\Facades\Car"
}

Et on pourra alors faire

Car::maMethode();

Conclusion

Laravel est un framework qui peut sembler simple au premier abord (à cause de sa syntaxe) mais qui renferme une structure interne beaucoup plus complexe. Cette manière de structurer les classes permet d'obtenir un résultat ultra modulable (on peut utiliser n'importe quelle classe n'importe où).

Cette philosophie permet de rendre le Framework très abordable pour les débutant, et très modulable pour les plus expérimenté. En revanche il faudra faire attention à bien organiser son code car Laravel offre un peu trop de liberté au niveau de sa structure MVC (Appel de model dans les Routes, Appel des vues dans les Routes...).