07 janvier 2026 - Gestion de dependances
Front Controller - les routes nommées
Je poursuis mon plan et j'implémente les features du Front Controller, ici les routes nommées.
Je constate qu'il y a un couplage fort entre le Router et les routes, que le routeur doit "attendre" la fin des définitions des routes pour compléter son tableau de routes nommées.
Le code est pas très élégant, la seule solution viable est d'utiliser des closures.
Je m'interroge, comment font Symfony et Laravel?
Ils utilisent tous les deux le concept: container IoC (inversion of control)
Laravel "Service Container" va donner la priorité à la flexibilité et à la résolution dynamique:
- Magie et Accessibilité: Le conteneur est souvent accessible via des "Facades" ou la fonction helper
app(). C'est très puissant mais cela peut inciter au "Service Locator" (un anti-pattern où on appelle le conteneur partout au lieu d'injecter). - Contextual Binding: Laravel excelle pour dire : "Si la classe A demande
Logger, donne-luiFileLogger, mais si c'est la classe B, donne-luiCloudLogger", avec une syntaxe très fluide. - Résolution à la volée: Par défaut, il résout beaucoup de choses au moment de l'exécution.
Symfony "DependencyInjection Component" va donner la priorité à la structure et au performances:
- Conteneur Compilé: En production, Symfony analyse tout le graphe de dépendances et génère une énorme classe PHP optimisée qui contient toutes les instanciations "en dur". C'est ultra-rapide.
- Rigueur extrême: Symfony encourage (et impose presque) que le conteneur soit "gelé". On ne peut pas modifier les services une fois le conteneur compilé.
- Compiler Passes: C'est la grande force de Symfony. Tu peux créer des classes qui modifient d'autres services au moment de la compilation (par exemple, chercher tous les services avec un tag
app.exporterpour les injecter automatiquement dans unExportManager).
Et pour River, quel approche?
Afin de ne pas se fermer la porte aux librairie externe, il faut implémenter l'interface Psr\Container\ContainerInterface PSR-11.
Pour l'autowiring (résoudre et injecter automatiquement les dépendances) utiliser la reflection ReflectionClass et ReflectionParameter, en php 8.5 c'est performant.
Il est conseillé de séparer l'enregistrement de la résolution: 1. Enregistrer les définitions, 2. Verrouiller le conteneur et 3. Résoudre les services (instanciation à la demande ou Singleton).
Gérer la plupart des services comme des singletons.
Je vais me servir ces Attributes de php afin de garder la config. proche du code.