Qu’est-ce que le conteneur de services
Le conteneur de services de Laravel est le mécanisme qui gère les dépendances des classes et effectue l’injection de dépendances. Injecter une dépendance, c’est fournir à une classe ce dont elle a besoin via son constructeur (ou parfois via un setter). Voyons l’exemple suivant.PodcastController a besoin d’aller chercher un podcast depuis Apple Music. On injecte donc un service capable de le faire. Cette injection permet aussi de remplacer facilement AppleMusic par un mock lors des tests.
Une bonne compréhension du conteneur de services est essentielle pour construire des applications Laravel de grande taille. C’est également utile si vous contribuez au cœur de Laravel.
Résolution sans configuration
Si une classe ne dépend que d’autres classes concrètes (pas d’interfaces), aucune configuration n’est nécessaire. Par exemple, dansroutes/web.php :
Cet exemple définit une classe dans le fichier de routes uniquement à des fins de démonstration. En pratique, placez vos services dans
app/Services.Service et l’injecte dans le handler. Aucune configuration nécessaire.
De nombreuses classes Laravel (contrôleurs, listeners, middlewares) reçoivent leurs dépendances automatiquement via le conteneur.
Bindings
Bindings de base
La plupart des bindings s’enregistrent dans un service provider. Dans un provider,$this->app donne accès au conteneur.
bind
bind associe une classe ou une interface à une closure.
App pour interagir avec le conteneur.
Les classes qui ne dépendent pas d’interfaces n’ont pas besoin d’être enregistrées. Le conteneur les résout automatiquement via réflexion.
singleton
singleton lie une classe/interface à une résolution unique. La même instance est renvoyée à chaque appel suivant.
instance
Vous pouvez également binder une instance existante avecinstance. Le conteneur renverra toujours cette instance.
Binding d’une interface à une implémentation
Une des grandes forces du conteneur : associer une interface à une implémentation. Par exemple, l’interfaceEventPusher et l’implémentation RedisEventPusher :
RedisEventPusher partout où EventPusher est demandé. Il suffit de type-hinter EventPusher dans le constructeur.
Résolution automatique (DI par type-hint)
Lorsqu’il résout un contrôleur, un listener ou un middleware, le conteneur inspecte les type-hints du constructeur et injecte automatiquement les dépendances.UserRepository ne dépend pas d’une interface, aucun enregistrement n’est nécessaire. Un simple accès à la route déclenche l’injection automatique.
Résolution depuis le conteneur
Méthode make
Résolvez une instance avec make.
makeWith permet de passer des arguments supplémentaires.
Injection automatique
En pratique, vous appelez rarementmake directement. Il suffit d’ajouter les type-hints dans le constructeur d’une classe résolue par Laravel (contrôleurs, listeners, middlewares) pour que l’injection se fasse automatiquement.
Façades et conteneur
Les façades fournissent une interface statique vers les objets du conteneur. Par exemple,Cache::get() récupère en interne le service Cache depuis le conteneur.
Exemple d’injection dans le constructeur
Voyons un pattern typique.1
Définir l'interface
2
Créer l'implémentation
3
Enregistrer le binding dans un service provider
4
Recevoir l'injection dans le contrôleur
Stripe vers un autre) se fait en modifiant un seul binding.
Prochaines étapes
Service providers
Apprenez à enregistrer des bindings via les service providers.