Drupal 8  8.0.2
Services and Dependency Injection Container

Data Structures

class  Container
class  PhpArrayContainer
class  CoreServiceProvider
class  ContainerBuilder
interface  ServiceModifierInterface
class  ServiceProviderBase
interface  ServiceProviderInterface

Detailed Description

Overview of the Dependency Injection Container and Services.

Overview and terminology

The Services and Dependency Injection Container concepts have been adopted by Drupal from the Symfony framework. A "service" (such as accessing the database, sending email, or translating user interface text) is defined (given a name and an interface or at least a class that defines the methods that may be called), and a default class is designated to provide the service. These two steps must be done together, and can be done by Drupal Core or a module. Other modules can then define alternative classes to provide the same services, overriding the default classes. Classes and functions that need to use the service should always instantiate the class via the dependency injection container (also known simply as the "container"), rather than instantiating a particular service provider class directly, so that they get the correct class (default or overridden).

See https://www.drupal.org/node/2133171 for more detailed information on services and the dependency injection container.

Discovering existing services

Drupal core defines many core services in the core.services.yml file (in the top-level core directory). Some Drupal Core modules and contributed modules also define services in modulename.services.yml files. API reference sites (such as https://api.drupal.org) generate lists of all existing services from these files, or you can look through the individual files manually.

A typical service definition in a *.services.yml file looks like this:

arguments: ['@path.crud', '@path.alias_whitelist', '@language_manager']

Some services use other services as factories; a typical service definition is:

- { name: cache.bin }
factory: cache_factory:get
arguments: [entity]

The first line of a service definition gives the unique machine name of the service. This is often prefixed by the module name if provided by a module; however, by convention some service names are prefixed by a group name instead, such as cache.* for cache bins and plugin.manager.* for plugin managers.

The class line either gives the default class that provides the service, or if the service uses a factory class, the interface for the service. If the class depends on other services, the arguments line lists the machine names of the dependencies (preceded by '@'); objects for each of these services are instantiated from the container and passed to the class constructor when the service class is instantiated. Other arguments can also be passed in; see the section at https://www.drupal.org/node/2133171 for more detailed information.

Services using factories can be defined as shown in the above example, if the factory is itself a service. The factory can also be a class; details of how to use service factories can be found in the section at https://www.drupal.org/node/2133171.

Accessing a service through the container

As noted above, if you need to use a service in your code, you should always instantiate the service class via a call to the container, using the machine name of the service, so that the default class can be overridden. There are several ways to make sure this happens:

As a note, you should always use dependency injection (via service arguments or create()/createInstance() methods) if possible to instantiate services, rather than service location (via the class), because:

Defining a new plugin type

If your module needs to define a new service, here are the steps:

Services can also be defined dynamically, as in the class, but this is less common for modules.

Service tags

Some services have tags, which are defined in the service definition. See Service Tags for usage.

Overriding the default service class

Modules can override the default classes used for services. Here are the steps:

See Also
Plugin API
Menu system