Dependency Injection Classes in Drupal 9 and 10

Dependency injection is a fundamental concept in modern software development and is also crucial in Drupal 9 and 10. Understanding the classes related to dependency injection in Drupal can significantly enhance your ability to manage and utilize services effectively within your codebase.

1. ContainerInterface:

The ContainerInterface is the foundation of Drupal's dependency injection system. It defines methods to get services from the container.

 

2. ContainerBuilder:

The ContainerBuilder class is responsible for building the service container. Developers use this class to register services and parameters. 

 

3. ContainerInjectionInterface:

Classes implementing ContainerInjectionInterface can access services from the dependency injection container. Implementing this interface grants access to the container for injecting services. 

 

4. ServiceModifierInterface:

 This interface allows services to be modified before they are used. It's useful for altering or enhancing services based on specific requirements. 

 

5. ServiceSubscriberInterface:

Classes implementing ServiceSubscriberInterface declare the services they use. This informs Drupal about the services required by the class. 

 

6. ServiceProviders:

Service providers (ServiceProviderInterface) are used to register services to the container. They define which services are available and how they are instantiated. 

7. ServiceInjectionTags:

Drupal allows services to be tagged with specific information using injection tags. These tags can categorize services and make them easier to find and use within the system. 

 

8. Service Decorators:

Drupal provides decorators that allow services to be wrapped or modified before they are used. This is useful for extending or altering the behavior of existing services.

 

Understanding these classes and interfaces is crucial for effectively utilizing Drupal's dependency injection system. It enables better modularization, testability, and flexibility within your codebase, allowing you to efficiently manage and inject services where needed.

By leveraging these classes, you can create more maintainable, decoupled, and scalable Drupal applications while adhering to best practices in software design and development.

Let's delve into some custom code examples to illustrate how dependency injection works in Drupal 9 and 10.

 

Example 1: Creating a Custom Service

First, let's create a simple custom service that provides a greeting message.

 

1. Define the Service Interface

Create a custom interface that defines the contract for our service:

// Custom module/src/GreetingServiceInterface.php
namespace Drupal\custom_module;
interface GreetingServiceInterface {
  public function getGreeting(): string;
}

 

2. Implement the Service

Create a class that implements the service interface:

// Custom module/src/GreetingService.php
namespace Drupal\custom_module;
class GreetingService implements GreetingServiceInterface {
  public function getGreeting(): string {
    return 'Hello, Drupal!';
  }
}

 

3. Register the Service

Register the service in the module's services.yml file:

# Custom module/custom_module.services.yml
services:
  custom_module.greeting_service:
    class: Drupal\custom_module\GreetingService
    tags:
      - { name: service }

 

Example 2: Using the Custom Service with Dependency Injection

Now, let's utilize our custom service in a controller using dependency injection.

 

1. Create a Controller

// Custom module/src/Controller/CustomController.php
namespace Drupal\custom_module\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\custom_module\GreetingServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class CustomController extends ControllerBase {
  protected $greetingService;
  public function __construct(GreetingServiceInterface $greetingService) {
    $this->greetingService = $greetingService;
  }
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('custom_module.greeting_service')
    );
  }
  public function greetingPage() {
    $message = $this->greetingService->getGreeting();
    return [
      '#markup' => $this->t($message),
    ];
  }
}

 

2. Define the Route

# Custom module/custom_module.routing.yml
custom_module.greeting:
  path: '/custom-greeting'
  defaults:
    _controller: '\Drupal\custom_module\Controller\CustomController::greetingPage'
    _title: 'Custom Greeting'
  requirements:
    _permission: 'access content'

 This code demonstrates the creation of a custom service and its usage in a controller via dependency injection. The service is registered and retrieved using dependency injection, ensuring that the GreetingService instance is available for use in the controller method.

This approach allows for better testability, modularity, and maintainability by decoupling components and leveraging Drupal's dependency injection container.

Share on social media

Add new comment