Symfony2 : Service Container

Voilà mon deuxième post qui entrera dans la catégorie des bonnes pratiques sur le framework Symfony2. Le Service Container est l’objet que vous utilisez probablement à outrance dans toutes les déclarations de Manager Symfony.

Comment déclare-t-on un Manager Symfony ?

1
2
3
4
services:
namespace.x.yManager:
class: Namespace\NameBundle\Manager\NameManager
arguments: [@service_container]

Si vous deviez déclarer un manager et que celui-ci devait être directement disponible depuis le « service container », vous le déclareriez de cette manière. Dans les arguments, vous indiqueriez les services à « injecter » au moment de la création. Vous pourriez alors atteindre ce manager de n’importe quel controller ou objet ayant accès au container, de cette manière :

1
$this->container->get(« namespace.x.yManager »);

Dans notre cas, l’argument @service_container correspond à l’objet « magique » qui contient tous les autres objets.

Pourquoi limiter l’utilisation du Service Container ?

Si vous prenez le temps de lire la documentation traitant du Composant d’Injection (Dependency Injection), ainsi que la page du cookbook du service container, vous pourrez constater qu’il n’est pas recommandé par Fabpot (the symfony gourou :p ), de ne pas devenir dépendant du container. Vous pourrez lire, qu’il est recommandé de fournir directement le ou les composant(s) qui nous intéresse, plutôt que de construire le service avec le container et de devoir par la suite chercher soit-même le service approprié. Pour plusieurs raisons :

  • Gain de performance
  • Gain de mémoire
  • Propreté du code
  • Limiter les dépendances dans le code

Comment limiter l’utilisation de ce super service ?

Au lieu d’utiliser le fameux @service_container, mieux vaut utiliser et injecter le ou les service(s) nécessaire(s). Par exemple au lieu d’injecter le super service pour accéder à l’ORM Doctrine, mieux vaudrait directement injecter l’entity manager correspondant à ce dont on a besoin.

1
2
3
4
5
services:
namespace.x.yManager:
class: Namespace\NameBundle\Manager\NameManager
arguments:
- "@doctrine.orm.entity_manager"

Comment trouver les services disponibles ?

Jusqu’à a rédaction de cet article, je me demandais comment trouver l’intégralité des services disponibles. Du coup, après une petite recherche sur le web, j’ai trouvé la solution pour vous. La solution se résume à une simple commande symfony.

1
php app/console debug:container

Avec cette commande, vous pourrez identifier les services disponibles. Grâce à cette commande vous pourrez sans soucis injecter les services disponibles.

Dans les arguments vous pourrez mettre par exemple mettre tous les services que vous voudrez.

Example :

1
2
3
4
arguments:
- "@doctrine.orm.entity_manager"
- "@doctrine.orm.other_entity_manager"
- "@swiftmailer.mailer.default"

Voilà, je pense que avoir fait le tour des injections disponibles sur Symfony2.