12.15.1. Dependency Injection в контроллере
В прошлой статье мы рассмотрели что такое Dependencies Injection:
12.15. Services и Dependency Injection.
В этой статье приведен пример кода с Dependency Injection в контроллере.
/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;
/**
* ModalFormContactController class.
*/
class ModalFormContactController extends ControllerBase {
/**
* The form builder.
*
* @var \Drupal\Core\Form\FormBuilder
*/
protected $formBuilder;
/**
* ModalFormContactController constructor.
*
* @param \Drupal\Core\Form\FormBuilder $form_builder
* The form builder.
*/
public function __construct(FormBuilder $form_builder) {
$this->formBuilder = $form_builder;
}
/**
* {@inheritdoc}
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The Drupal service container.
*
* @return static
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('form_builder')
);
}
/**
* Callback for modal form.
*/
public function openModalForm() {
$response = new AjaxResponse();
$modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
$enquiry_title = $this->t("Send an enquiry to @business_name", ['@business_name' => $modal_form['business_name']['#value']]);
$response->addCommand(new OpenModalDialogCommand($enquiry_title, $modal_form));
return $response;
}
}
Давайте разберем части кода для DI (Dependency Injection).
namespace Drupal\drupalbook\Controller;
Сначала мы указываем namespace (пространство имен), место в котором этот файл лежит, где drupalbook это машинное имя вашего модуля.
use Symfony\Component\DependencyInjection\ContainerInterface;
Подключаем класс ContainerInterface, позже мы будем использовать для получения объектов из Service Container.
/**
* The form builder.
*
* @var \Drupal\Core\Form\FormBuilder
*/
protected $formBuilder;
Объявляем свойство в котором мы будем хранить объект из Service Container. Комментарий @var \Namespace помогает вашей IDE понять какие методы объекта показывать в автокомплите.
/**
* ModalFormContactController constructor.
*
* @param \Drupal\Core\Form\FormBuilder $form_builder
* The form builder.
*/
public function __construct(FormBuilder $form_builder) {
$this->formBuilder = $form_builder;
}
Дальше в конструкторе нужно получить в параметре объект из Service container, этот объект мы будем создавать в следующем методе create(), а здесь мы получаем объект и сохраняем в свойство, объявленное выше $formBuilder. Если вы подключаете новый сервис, то его нужно добавлять параметр за параметром в __construct(). Так что если вы собрались подключить 10 сервисов, то у вас будет 10 параметров.
/**
* {@inheritdoc}
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The Drupal service container.
*
* @return static
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('form_builder')
);
}
В методе create мы получаем объект Service container и возвращаем объект $form_builder, которые в коде выше в конструкторе мы сохраняем в свойства для объектов (formBuilder). Обратите внимание на регистр переменных для объектов из Service container мы используем lowercase ($form_builder), а для свойств в классе, куда мы эти объекты сохраняем, мы используем camelCase с маленькой буквы (formBuilder).
И теперь мы можем использовать объект из Service Container в методах нашего класса:
/**
* Callback for modal form.
*/
public function openModalForm() {
...
$modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
...
}