How to inject services in Drupal – a step by step tutorial

What is dependency injection 

Dependency injection is  a design pattern in Object oriented programming where we can pass existing object or services to a  class and use its functions with out bothering about its implementation.

Dependency injection is used to make a class independent of its dependencies or to create a loosely coupled program. Dependency injection is useful for improving the reusability of code.

Need for dependency injection in Drupal

In Drupal it is highly recommended to use dependency injection in classes instead of  calling directly services or classes.

For example, we can directly call services as below.

\Drupal::service(‘path.alias_manager’)

But this is not recommended. As a best practice, a decoupled approach we have to follow. For this purpose we have dependency injunction.

In Drupal,  we can  Inject  Core Services to custom  forms, controllers and blocks.

For example database service is a one of the Core service in Drupal, this we can use any where  in Drupal code without bothering about which database and Sql syntax  is used in respective to that database. we can inject database service into the form, controller etc, and use functions in database service for various operations without bothering which database Drupal connected.

In this article we are discussing about what are all the changes need to make in a class for injecting an existing a service.

Note:Normally for dependency injunction,  class has to implement ContainerInjectionInterface, But in Drupal, most case, form or controller class will be implementing FormaBase class or conrollerBase class, since these base classes already implements ContainerInjectionInterface class  then no need to implement this in our custom form or controller class.

You can see all available core services in your below project path.

/your_project/core/core.services.yml

Also you can search for core services from below page for all drupal versions.

https://api.drupal.org/api/drupal/services/10

Here we are injecting a messenger core service into a custom form.

For dependency injection, we need do below steps in our class

  • Step 1- add  Object variable in Class
  • Step-2 – add Create() function in class
  • Step-3- Class constructor which  saves value from previous method in object property created in step 1.
  • Step -4   Call the service functions using variable created in step1

In this article we are creating a simple form where we are going to display submitted details in same page after submission of the form using messenger service available in Drupal Core services.

So create custom a module with a custom form.

You can use this Drupal form code creator,

We have below custom module with one student form.

You can download complete sample module here.

So in our custom form we are  following below steps for injecting messenger service

Add below line  in top of your form class for importing container interface.

use Symfony\Component\DependencyInjection\ContainerInterface;

Since here we are using messenger service, we have to import MessengerInterface class as below.

use Drupal\Core\Messenger\MessengerInterface;

We are following below steps for injecting messenger service.

1- Create An object property  

Add an object variable to save the value passed in the class constructor. So here we are adding below $messenger variable inside our form class StudentForm in path – /src/Form/StudentForm.php

//**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;

2-Create() method in class

Add a  static  public create() method that gets the values from the dependency container, and creates a new object of your class. So inside your class create below create function with container Interface.

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('messenger')
);
}

 create () function loads one or more services, that may be a core service in  core.services.yml or any custom service in module  *.services.yml file. 

Please note,  create method is a  part of the class Drupal\Core\DependencyInjection\ContainerInjectionInterface  which allows controllers/forms/service classes  to be instantiated with a service.

Here  Drupal\Core\Form\FormBase already implements this interface. Any form that extends Drupal\Core\Form\FormBase  no need to implement above interface.

3- Class constructor to save value

Add a  class constructor that saves the values passed from the previous method in object properties. 

/**
* Constructs a object.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
*/
public function __construct( MessengerInterface $messenger) {


$this->messenger = $messenger;
}

 Inside constructor  uses the services that are loaded by StudentForm::create and stores them in properties of the class. If you have more services, the order in which the services are loaded in SrudentForm::create must be equal to the order of the parameters in the StudentForm::__construct method.

Step 4- Call the service functions

Finally we are calling service function using object variable created in step-1 with $this keyword.

Here we are using below addMessage() function for displaying message with submitted details in form.

$this->messenger->addMessage();

So our submit function will look like below, 

/**
* {@inheritdoc}
*/
public function submitForm(array & $form, FormStateInterface $form_state) {
$stud_name = $form_state->getValue('student_name');
$subject = $form_state->getValue('subject');
$marks = $form_state->getValue('marks');
$this->messenger->addMessage( $this->t('You have provided name as %stud_name subject as %subject and marks as %marks', ["%stud_name"=>$form_state->getValue('student_name'),"%subject"=>$form_state->getValue('subject'),"%marks"=>$form_state->getValue('marks')]));
}

$t() function second parameter should be an array();

After submit form, you can see the submitted values as below.

Complete source code of this custom module you can download here.

Get Free E-book
Get a free Ebook on Drupal 8 -theme tutorial
I agree to have my personal information transfered to MailChimp ( more information )
if you like this article Buy me a Coffee this will be an ispiration for me to write articles like this.

You may also like...