Injection de dépendances dans Symfony : services et autowiring
L'injection de dépendances dans Symfony : le conteneur crée les services et, par l'autowiring, les passe aux classes qui les demandent dans leur constructeur.
class Cuisine { public function __construct(private readonly PlatRepository $plats) { } public function platDuJour(): ?Plat { return $this->plats->findOneBy(['specialite' => true], ['id' => 'ASC']); } } class MenuController extends AbstractController { public function __construct(private readonly Cuisine $cuisine) { } }
Chaque classe de src/ devient un service sans configuration : typer un argument du constructeur suffit pour que le conteneur fournisse l'instance, la même pour toute la requête. Une classe ne crée plus ses dépendances, elle les reçoit ; la logique métier quitte le contrôleur, et l'on change la source des données sans toucher à ceux qui s'en servent. Les actions de contrôleur peuvent aussi recevoir un service en argument (Cuisine $cuisine), ce que les autres services ne font pas. debug:autowiring liste les types disponibles. Le piège : l'autowiring résout des classes et des interfaces, pas des valeurs. Un argument string $cle dans un constructeur fait échouer la construction du conteneur tant qu'on ne lui donne pas sa valeur, par exemple avec #[Autowire('%env(CLE)%')].
Les exercices font sortir la liste des plats du contrôleur pour la confier à un service Cuisine, injecté dans les contrôleurs de la carte et de l'accueil, puis injecter à ce service le PlatRepository pour qu'il lise la carte en base, sans changer une ligne des contrôleurs.
2 exercices font travailler cette notion, en écrivant du code dans le navigateur.
Dans les parcours
- Le chef cuisinier Symfony pour les devs PHP · chapitre 1 : Premiers pas à la taverne
- La carte sort de la base Symfony pour les devs PHP · chapitre 2 : La cave et le garde-manger