L'Injection de Dépendance dans Symfony : Une Force Cachée

Imen EZZINE

@imenezzine

  @imenezzine1

 

Développeuse PHP Symfony
  • Symfony 1.x : une approche rigide

    •  

Text

class UserController
{
    public function index()
    {
        $userService = new UserService(); // Instanciation directe
        $users = $userService->getAllUsers();
        return $this->render('users/index', ['users' => $users]);
    }
}

Symfony 2 est sorti le 28 juillet 2011. 🎉

  • Le composant DependencyInjection,

  • L’architecture bundle,

  • L’intégration poussée avec Composer (arrivé un peu plus tard),

  • L’approche RESTful, l’autoloader PSR-0, etc.

 

Un vrai tournant dans l'histoire du framework !

 

🤔 Le composant DependencyInjection, c'est quoi ?

 

🛠 Pourquoi l'utiliser ?

services:
    App\Service\UserService:
        arguments:
            $repository: '@App\Repository\UserRepository'

Définition d'un service dans services.yaml :

namespace App\Controller;

use App\Service\UserService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class UserController extends AbstractController
{
    private $userService;

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

    public function index()
    {
        $users = $this->userService->getAllUsers();
        return $this->render('users/index.html.twig', ['users' => $users]);
    }
}

Symfony 3 : Simplification avec l'autowiring

 

services:
    App\Service\UserService: ~ # Autowiring activé automatiquement
namespace App\Controller;

use App\Service\UserService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class UserController extends AbstractController
{
    public function index(UserService $userService)
    {
        $users = $userService->getAllUsers();
        return $this->render('users/index.html.twig', ['users' => $users]);
    }
}

Symfony 4 et au-delà : Évolutions modernes

 

 

L'ajout de ce composant a eu plusieurs effets importants :

  1. Révolution de l'écosystème PHP : Symfony 2.0 a bouleversé la façon dont les applications PHP étaient structurées et développées3.

  2. Nouvelle philosophie : Le concept de services et l'injection de dépendances ont introduit une nouvelle approche dans la conception des applications Symfony3.

  3. Apprentissage nécessaire : Les développeurs ont dû réapprendre le framework, car la version 2.0 était radicalement différente de la précédente3.

Impacts de l'introduction

Découplage 
Facilité de maintenance
Testabilité améliorée 
Performance optimisée 

 

Depuis son introduction, le composant d'injection de dépendances a continué d'évoluer :

  • Il est devenu plus puissant et central au framework au fil des versions1.

  • Les versions récentes de Symfony (comme Symfony 6) ont simplifié son utilisation avec des fonctionnalités comme l'autowiring et l'autoconfiguration4.

L'injection de dépendances reste un concept fondamental dans Symfony, permettant une meilleure organisation du code, une plus grande flexibilité et une maintenance plus aisée des applications.

Évolution du composant

class UserService {
    private Database $db;

    public function __construct() {
        $this->db = new Database();
    }
}

 Avant et après le composant DependencyInjection

🔴 Avant Symfony et son conteneur de services

 

Problèmes :

  • Dépendance forte avec Database
  • Code rigide et difficilement testable
  • Pas de gestion centralisée des services

🟢 Après : Symfony et son conteneur de services

use Symfony\Component\DependencyInjection\Attribute\Autowire;

class UserService {
    public function __construct(
        #[Autowire(service: 'database_connection')]
        private Database $db
    ) {}
}

Avantages :

  • Code plus flexible et testable
  • Configuration centralisée
  • Meilleure maintenabilité

 Symfony 6.1 : Introduction de #[Autowire]

use Symfony\Component\DependencyInjection\Attribute\Autowire;

class MyService {
    public function __construct(
        #[Autowire(service: 'my_dependency')] private MyDependency $dependency
    ) {}
}

Avantages :

  • Plus besoin de config YAML/XML
  • Injection visible directement dans le code

 Symfony 6.1 : #[Autoconfigure]

 

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

#[Autoconfigure]
class MyService {}

Permet d’activer automatiquement l’autowiring et les tags

Merci!

Des questions ?

Bento

By imenezzine

Bento

  • 20