9.15.1. Dependency Injection in Controller
In the last article, we looked at what Dependencies Injection is:
9.15. Services and Dependency Injection.
This article provides sample code with Dependency Injection in a controller.
Code examples can be viewed on github:
https://github.com/levmyshkin/drupalbook8
/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;
}
}
Let's take a look at some of the code for DI (Dependency Injection).
namespace Drupal\drupalbook\Controller;
First we specify the namespace where this file is located, where drupalbook is the machine name of your module.
use Symfony\Component\DependencyInjection\ContainerInterface;
We include ContainerInterface class, later we will use it to get objects from the Service Container.
/**
* The form builder.
*
* @var \Drupal\Core\Form\FormBuilder
*/
protected $formBuilder;
We declare a property in which we will store an object from the Service Container. The @var \Namespace comment helps your IDE understand which object methods to show in autocomplete.
/**
* ModalFormContactController constructor.
*
* @param \Drupal\Core\Form\FormBuilder $form_builder
* The form builder.
*/
public function __construct(FormBuilder $form_builder) {
$this->formBuilder = $form_builder;
}
Further in the constructor, you need to get an object from the Service container in the parameter, we will create this object in the next create() method, and here we get the object and save it to the property declared above $formBuilder. If you connect a new service, then you need to add it parameter by parameter to __construct(). So if you are going to connect 10 services, then you will have 10 parameters.
/**
* {@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')
);
}
In the create method, we get the Service container object and return the $form_builder object, which in the code above in the constructor we save into the properties for the objects (formBuilder). Pay attention to the case of variables for objects from the Service container, we use lowercase ($form_builder), and for properties in the class where we save these objects, we use camelCase with a lowercase first letter (formBuilder).
And now we can use an object from the Service Container in the methods of our class:
/**
* Callback for modal form.
*/
public function openModalForm() {
...
$modal_form = $this->formBuilder->getForm('Drupal\drupalbook\Form\ModalForm');
...
}