How to Add Dependency Injection in a Controller in Drupal 9
Dependency Injection is a design pattern that helps decouple the different components of a software application. It is a software design pattern that helps to manage the dependencies between different components in a software system. It involves passing the required dependencies into a class, rather than letting the class create or locate them itself.
This pattern makes writing reusable, testable, and maintainable code easier. Decoupling the components of a system makes it easy to change or update any one component without affecting the others. In this blog, I will outline the process of creating and utilizing a custom service in Drupal 9 through dependency injection.
Dependency injection is a technique where a client object relies on an injected object. It facilitates the flow of data between the two objects and enhances the overall modularity, testability, and scalability of the application.
Dependency Injection has several benefits, such as:
- Improved maintainability: Dependency Injection makes it easier to change or update components without affecting the rest of the system.
- Increased flexibility: Different components can be easily swapped out and replaced with others, which can be especially useful for testing.
- Better scalability: Dependency Injection allows new components to be added easily as the application grows.
Dependency Injection can be implemented in different ways, such as using a constructor, a setter method, or an interface. The choice of method depends on the requirements of the specific use case, but the overall goal is to make the dependencies explicit and manageable.
Implementing Dependency Injection in Drupal 9
Recently, I have been working with services and dependency injection in Drupal 9. This process is similar to what was used in Drupal 8. Dependency injection provides a major advantage as it eliminates the need to constantly call the global container. Instead, we can simply inject the required services and events through dependency injection.
Services in Drupal 9 can be created using custom modules and can then be utilized on pages, controllers, blocks, and other components by using dependency injection.
In the below example, I have explained the connection between services and dependency injection in Drupal 9. I will also talk about how to call a custom service, which lists nodes based on the user ID passed in the URL, within a custom controller using dependency injection.
Services are used to reuse functionality such as database-related queries or sending emails. By using services, the same functionality can be utilized throughout the site after being defined in a single service file.
Step-Wise Guide on How to Add Dependency Injection in a Controller in Drupal 9
Let us go step by step to implement a service and invoke it via Dependency Injection in a Controller.
Step 1 - Establish a Custom Module within the Appropriate Directory
The first step is to create a custom module within the designated directory. This module should include an info.yml file that outlines the name and relevant details of the custom module.
Step 2 - Implement a Custom Service for Retrieving Node List Based on User ID
To proceed, we will add a module_services.yml file, as illustrated in the image below. Within this file, we will specify the service class and its dependencies, such as the database argument in this case, as it involves querying the database to obtain the node list.
Next, we will place the service file within the designated directory, as follows:
This is the location of the custom service file, which in this case is named GetDataServices.php and resides within the src folder of the custom module.
Step 3 - Integrate the Controller and Router within the Custom Module
This step involves adding the necessary code to the controller, which allows us to utilize the service from within the controller. The following code demonstrates this implementation.
The central aspect of this implementation is the utilization of the $container object, which offers a single method, "Get", as follows:
To commence, we will declare a variable, referred to as $nodedata.
Subsequently, we set the value of $container with the following line:
This specifies the name of our custom service, custom_service.get_data_user_node, which will be instantiated in the backend.
To access any function within the custom service, we first need to retrieve it using the following line:
$service = \Drupal::service('custom_service.get_data_user_node');
But we are calling the Dependency injection so we just inject our service like : $this->nodeData.
Finally, we can call the desired function, in this case the, "drupalise($id)" function, by using the following line:
$all_node = $this->nodeData->drupalise($id);
This function, "drupalise($id)," retrieves the node list based on the User ID argument passed.
Step 4 - Verifying the Controller Routing Page
The routing page of the controller can be accessed by passing the User ID in the URL. The data related to the user ID will be displayed on the page. The functionality of the page, such as filters and sorting, can be enhanced by adding the necessary code in the service file.
In this instance (Fig. 1), a simple listing query has been included and the result is presented in a tabular format with headers and rows. The controller function returns this table with the listing of Uid : Node id of that user, Title , and Node Type.
This serves as an illustration of how to access the first service from the container in Drupal 9 using dependency injection. This approach can be applied to call both Drupal core services and custom services.
To take advantage of the full capabilities of the Drupal 9 platform and to simplify your custom module development process, you should consider utilizing dependency injection in your controllers.
This approach allows you to leverage the power of custom services and streamline the integration of your desired functionality into your website.
If you are looking to improve your Drupal application’s performance and efficiency, or Drupal development needs, reach out to us.