-
Notifications
You must be signed in to change notification settings - Fork 0
Principes de base
Le travail du container de service, c'est de préparer des outils pour les rendre facilement et rapidement disponibles à l'utilisation.
On peut connaitre tous ces services avec la commande :
symfony console debug::autowiring --allLes services présents dans cette longue liste, sont passés par référence afin de ne pas compromettre les performances.
Un Controller, peut recevoir grâce au type-hinting n'importe lequel de ces services, car il est associé à une route
pour la gestion de la requête.
#[Route('/', name: 'homepage')]
NomDeMonController(Service $service)
{
...
}Cette "magie" est rendue possible, en partie grâce à plusieurs fichiers:

config/bundles.php, lui s'occupe d'injecter dans le container de services, tous les bundles du framework grâce au composant
Symfony Flex.
Rien d'autre à faire ! Dès qu'un bundle est installé, il est ajouté a cette liste.

config/services.yaml quand à lui, permet de paramétrer un peu plus en profondeur.
parameters:
services:
# default configuration for services in this file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'A noter, avec cette configuration l'ensemble du dossier /src est automatiquement injecté.
il faut préciser les sous-dossiers à exclure, ici 3, /src/DependencyInjection/,
/src/Entity/, /src/Kernel.php.
La clef autowiring ayant pour valeur true, cela va ainsi permettre d'aller 'piocher' rapidement dans le container de service le service souhaité.
Exemple: Une classe à besoin d'un service
namespace App\Service;
use App\Util\Service;
class JaiBesoinDunService
{
private $transformer;
public function __construct(Service $transformer)
{
$this->transformer = $transformer;
}
public function faireQuelqueChose($s): void
{
$serviceRendu= $this->transformer->operate($s);
}
}namespace App\Util;
class Service
{
public function operate(string $s): string
{
return (string)$s;
}
}Avec la configuration par défaut les deux classes sont automatiquement enregistrées en tant que services et configurées pour être câblées automatiquement . On peut donc les utiliser sans aucune configuration.
Il est aussi possible les déclarer dans services.yaml mais c'est redondant:
services:
_defaults:
autowire: true
autoconfigure: true
# ...
App\Service\JaiBesoinDunService:
autowire: true
App\Util\Service:
autowire: trueToutefois injecter des services dans le container de cette méthode est envisageable.
Si l'on souhaite aller plus loin il est possible de créer des alias, où par exemple l'id n'est pas un nom de classe.
# config/services.yaml
services:
# ...
# the id is not a class, so it won't be used for autowiring
app.service.transformer:
class: App\Util\Service
# ...
# but this fixes it!
# the ``app.service.transformer`` service will be injected when
# an ``App\Util\Service`` type-hint is detected
App\Util\Service: '@app.service.transformer'Les alias sont utilisés par les bundles principaux pour permettre aux services d'utiliser l'autowiring. Par exemple, MonologBundle crée un service dont l'id est logger. Mais il ajoute également un alias : Psr\Log\LoggerInterface qui pointe vers le loggerservice. C'est pourquoi les arguments avec indication de type Psr\Log\LoggerInterface peuvent être câblés automatiquement.
ℹ️ Il est possible d'aller encore plus loin par exemple pour travailler avec des interfaces.