Comprendre les services — Formation Symfony 7

Le système de service et d’injection de dépendances de Symfony est un outil puissant qui permet de découpler les composants de son application et de les rendre plus testables et maintenables.

Qu’est-ce qu’un service ?

Un service est un objet qui fournit une fonctionnalité spécifique à l’application. Ce n’est qu’une classe qui peut être plus ou moins complexe en fonction de la situation.

Au cœur de Symfony se cache un conteneur d’inversion de contrôle (IoC) qui permet de gérer les services de votre application. C’est une objet qui permet de construire des objets en fonction des besoin en indexant les objets avec une clef particulière.

Si on regarde le code source de la fonction render() que l’on utilise depuis le début de cette formation on retrouve le code suivant :

$twig = $this->container->get('twig');

Symfony demande au conteneur une instance de l’objet Twig qui gère le rendu HTML.

l’injection de dépendances

L’injection de dépendances est un principe de conception qui consiste à fournir aux objets les dépendances dont ils ont besoin pour fonctionner. Cela se fait en injectant les dépendances dans le constructeur de l’objet (ou plus rarement via un setter).

class MailNotification

{

    public function __construct(private readonly MailerInterface $mailer){
    }

    // ...
    
}

L’avantage est que le conteneur va être capable de résoudre les dépendances d’un objet automatiquement et injecter les services nécessaires automatiquement. Si vous voulez la liste des services qui sont disponibles par défaut et qui sont câblés automatiquement vous pouvez utiliser :

php bin/console debug:autowiring

Les controllers

Les controllers sont des classes spéciales qui bénéficie aussi de ce système d’injection dans leurs actions. C’est ce qui permet par exemple de récupérer le manageur d’entité ou les repository.

<?php

namespace App\Controller\Admin;

use App\Form\RecipeType;
use App\Repository\RecipeRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route("/admin/recettes", name: 'admin.recipe.')]
class RecipeController extends AbstractController
{

    #[Route("https://grafikart.fr/", name: 'index')]
    public function index(
        RecipeRepository $repository, 
        Request $request, 
    ): Response
    {
        $page = $request->query->getInt('page', 1);
        $recipes = $repository->paginateRecipes($page);
        return $this->render('admin/recipe/index.html.twig', [
            'recipes' => $recipes,
        ]);
    }

Liens utiles