le IOC pour Injection Object Container est la méchanique de Laravel pour compléter le concept énoncé dans mon précédent poste. Maintenant que tu as compris le concept de développement par contrat, il faut savoir qu'en pratique pour que cela fonctionne tu dois respecter une certaine logique :
<?php
class MyDependance implements MyDependanceInterface
{
// [...]
}
class BadClass
{
protected $myDependance;
public function __construct()
{
$this->myDependance = new MyDependance();
}
}
class GoodClass
{
protected $myDependance;
public function __construct(MyDependanceInterface $myDependance)
{
$this->myDependance = $myDependance;
}
}
La classe GoodClass et BadClass font la même chose, à savoir "peupler" un attribut "myDependance" avec un object de type "MyDependanceInterface" (petite tips : MyDependance à en réalité 2 types à savoir MyDependanceInterface et MyDependance)
La différence majeur est que BadClass embarque une dépendance en dure, c'est à dire que dans le code de ta classe, tu instancies un objet directement. Tu n'as donc pas un code générique. Si demain tu créé une nouvelle classe avec le type MyDependanceInterface, tu devras aussi changer la class BadClass pour pouvoir l'utiliser.
Il faut donc passer les dépendances comme attribut dans ton constructeur (ou un setter). On appel ça l'injection de dépendance. à noter que j'ai pris soin de bien mettre MyDependanceInterface comme type de mon paramètre pour le rendre générique.
Laravel te propose donc 3 méthodes pour faire ça simplement :
Pour le moment nous allons regarder uniquement bind et make, tu regarderas singleton sur la documentation.
make permet de créé un objet. Bind permet d'attacher une factory (comprendre un methode qui sera automatiquement appelé pour "construire" ou "instancier" ton objet) à un type.
Ainsi dans mon exemple tu peux faire :
/**
A chaque fois que tu veux créé un objet de type MyDependanceInterface (donc par extension MyDependance), la méthode ci dessous sera appelé.
**/
$this->app->bind(MyDependanceInterface::class,function($app){
// Si tu veux retourner un nouveau type ici, tu as juste à changer cette ligne et tout fonctionnera :)
return new MyDependance();
});
/**
* Comme au dessus mais pour GoodClass, et comme tu vois, tu passes directement l'object en paramètre.
**/
$this->app->bind(GoodClass::class,function($app){
return new GoodClass($app->make(MyDependanceInterface::class));
});