Module Development
Topic

Dependency Injection for Drupal 8, 9, and 10

Dependency injection is a design pattern commonly used in object-oriented software architectures in order to support Inversion of Control. At a very high level it refers to the practice of passing existing objects (or services) into a class when it is instantiated, or via a setter method, rather than creating them inside the class itself. Doing so allows some other logic external to your code to determine how to initialize and configure the service object, and keeps your code more flexible.

In the case of Drupal this allows your code to state a need, such as, “I need to access the database. Please provide me with a database service,” without knowing anything about the specifics. Drupal then determines, based on other factors, what database type (MySQL, SQLite, etc.) is being used, and how to connect to it, how to authenticate, and any other requirements on your behalf.

Currently in Drupal, dependency injection is the preferred method for accessing and using services and should be used whenever possible. Rather than calling out to the global services container, services are instead passed as arguments to a constructor or injected via setter methods. This allows for a loose coupling of components, which makes things easier to test, and easier to replace with alternative implementations.

Example tasks

  • Use dependency injection to make use of services in your module’s code
  • Write custom code that is easier to test and refactor

Confidence

While relatively new to Drupal, dependency injection is a tried and true technique commonly used in object-oriented PHP applications. The implementation in Drupal is unlikely to change significantly, and therefore you should feel comfortable learning it just about any context and then applying it to Drupal.

Drupalize.Me resources

Categories
Drupal 8, 9, 10, and 11
More information

As a development framework, Drupal core includes services for doing common things like accessing the database, sending email, or making HTTP requests. You can make use of these services to perform certain tasks, instead of recreating them in your own code. This means less custom code that you need to write and maintain. Generally speaking, almost everything that Drupal does is actually done by one of these objects. In Drupal, these objects are called services and in order to make working with them easier, they are primarily accessed through the service container.

In this tutorial, we'll:

  • Explain the role of services in Drupal.
  • Introduce the service container.

By the end of this tutorial, you'll understand the basics concepts of services and the service container in Drupal module development.

Categories
Drupal 8, 9, 10, and 11
More information

Dependency injection is an object-oriented programming design pattern widely used in Drupal. Instead of a class creating an object directly, dependency injection provides services or objects to a class externally, and is an example of the Inversion of Control principle.

In this tutorial, we'll:

  • Explain dependency injection in the context of Drupal.
  • Take a look at examples of constructor and setter injection in Drupal code.

By the end of this tutorial, you'll recognize dependency injection patterns and understand how it's used in Drupal module development.

More information

To access services in Drupal through the service container, you'll need to know the unique machine name of the service. We'll use the example of making HTTP requests to a weather forecast API in the anytown module to demonstrate several methods you can use to identify an existing service's ID.

In this tutorial, we'll:

  • Discover existing services and their machine names.
  • Take a look at an example service definition.

By the end of this tutorial, you should be able to locate and use existing services in your Drupal module.

Categories
Drupal 8, 9, 10, and 11
More information

It's best practice to access any of the services provided by Drupal via the service container to ensure the decoupled nature of these systems is respected. In order to do so, you need to know what services exists, and then, where possible, use dependency injection to use them in your code.

This tutorial walks through the process of:

  • Discovering existing services and learn their machine name
  • Using the machine name of service to request a copy from the service container

Services

Topic
Categories
Drupal 8, 9, and 10
More information

Services are objects that encapsulate the code for performing specific tasks in a reusable and decoupled way.

Drupal 8, 9, 10, and 11
More information

Object-oriented PHP utilizes classes and objects to organize code into reusable chunks. This approach helps us organize complex applications, such as Drupal, into modular code called classes that can be reused across the entire system.

Guides

Not sure where to start? Our guides provide useful learning tracks for all skill levels.

Navigate guides

External resources

  • Services and dependency injection (Drupal.org)
    • Examples of how to use dependency injection in a Drupal context.
  • Services and Dependency Injection Container (api.drupal.org)
    • A more technical look at how Drupal implements dependency injection and services
  • Dependency Injection (phptherightway.com)
    • A good overview of dependency injection and related concepts with a focus on PHP applications. Contains a well-curated list of links to other articles that discuss the various concepts in detail
  • Late Static Binding (php.net)
    • Drupal makes use of a PHP feature known as late static binding to handle injection of services in many cases. See \Drupal\system\Plugin\Block\SystemBrandingBlock::create() for an example. This isn’t necessarily required knowledge, but if you’re curious how that code works you can read up on late static binding.