12.15.1. Injection de dépendances dans un contrôleur
Dans l’article précédent, nous avons examiné ce qu’est l’Injection de Dépendances :
12.15. Services et Injection de Dépendances.
Dans cet article, un exemple de code avec Injection de Dépendances dans un contrôleur.
/modules/custom/drupalbook/src/Controller/ModalFormContactController.php :
<?php
namespace Drupal\drupalbook\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\OpenModalDialogCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormBuilder;
/**
* Classe ModalFormContactController.
*/
class ModalFormContactController extends ControllerBase {
/**
* Le form builder.
*
* @var \Drupal\Core\Form\FormBuilder
*/
protected $formBuilder;
/**
* Constructeur de ModalFormContactController.
*
* @param \Drupal\Core\Form\FormBuilder $form_builder
* Le form builder.
*/
public function __construct(FormBuilder $form_builder) {
$this->formBuilder = $form_builder;
}
/**
* {@inheritdoc}
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* Le conteneur de services Drupal.
*
* @return static
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('form_builder')
);
}
/**
* Callback pour le formulaire modal.
*/
public function openModalForm() {
$response = new AjaxResponse();
$modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
$enquiry_title = $this->t("Envoyer une demande à @business_name", ['@business_name' => $modal_form['business_name']['#value']]);
$response->addCommand(new OpenModalDialogCommand($enquiry_title, $modal_form));
return $response;
}
}
Examinons les parties du code pour l’Injection de Dépendances (DI).
namespace Drupal\drupalbook\Controller;
Tout d’abord, on indique le namespace (espace de noms), le chemin où se trouve ce fichier, où drupalbook est le nom machine de votre module.
use Symfony\Component\DependencyInjection\ContainerInterface;
On importe la classe ContainerInterface, que nous utiliserons plus tard pour récupérer des objets depuis le conteneur de services.
/**
* Le form builder.
*
* @var \Drupal\Core\Form\FormBuilder
*/
protected $formBuilder;
On déclare une propriété pour stocker l’objet provenant du conteneur de services. Le commentaire @var \Namespace aide votre IDE à proposer les bonnes méthodes en autocomplétion.
/**
* Constructeur de ModalFormContactController.
*
* @param \Drupal\Core\Form\FormBuilder $form_builder
* Le form builder.
*/
public function __construct(FormBuilder $form_builder) {
$this->formBuilder = $form_builder;
}
Ensuite, dans le constructeur, on reçoit en paramètre l’objet depuis le conteneur de services. Cet objet est créé dans la méthode create() ci-dessous, et ici on l’assigne à la propriété déclarée plus haut $formBuilder. Si vous ajoutez un nouveau service, il faut ajouter un paramètre par paramètre dans __construct(). Donc si vous devez injecter 10 services, vous aurez 10 paramètres.
/**
* {@inheritdoc}
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* Le conteneur de services Drupal.
*
* @return static
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('form_builder')
);
}
Dans la méthode create, on récupère l’objet du conteneur de services et on retourne cet objet $form_builder que l’on stocke dans la propriété $formBuilder du constructeur. Notez la casse : pour les variables provenant du conteneur, on utilise le format lowercase ($form_builder), et pour les propriétés de la classe, on utilise camelCase avec une lettre minuscule (formBuilder).
Nous pouvons maintenant utiliser l’objet du conteneur de services dans les méthodes de notre classe :
/**
* Callback pour le formulaire modal.
*/
public function openModalForm() {
...
$modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
...
}