Skip to content

Dependency Injection

Drush command files obtain references to the resources they need through a technique called dependency injection. When using this programing paradigm, a class by convention will never use the new operator to instantiate dependencies. Instead, it will store the other objects it needs in class variables, and provide a way for other code to assign an object to that variable.

Tip

Drush 11 and prior required dependency injection via a drush.services.yml file. This approach is deprecated in Drush 12+ and removed in Drush 13.

Autowire

12.5+

Command files may inject Drush and Drupal services by adding the AutowireTrait to the class (example: PmCommands). This enables your Constructor parameter type hints to determine the injected service. When a type hint is insufficient, an #[Autowire] Attribute on the constructor property (with service: named argument) directs AutoWireTrait to the right service (example: FieldDefinitionCommands).

If your command is not found by Drush, add the -vvv option for debug info about any service instantiation errors. If Autowire is still insufficient, a commandfile may implement its own create() method (see below).

create() method

11.6+

Command files not using Autowire may inject services by adding a create() method to the commandfile. The passed in Container is a League container with a delegate to the Drupal container. Note that the type hint should be to Psr\Container\ContainerInterface not Symfony\Component\DependencyInjection\ContainerInterface. A create() method and constructor will look something like this:

class WootStaticFactoryCommands extends DrushCommands
{
    protected $configFactory;

    protected function __construct($configFactory)
    {
        $this->configFactory = $configFactory;
    }

    public static function create(Psr\Container\ContainerInterface $container): self
    {
        return new static($container->get('config.factory'));
    }
See the Drupal Documentation for details on how to inject Drupal services into your command file. This approach mimics Drupal's blocks, forms, and controllers.

createEarly() method

12.0+

Drush 12 supported a createEarly() method. This is deprecated and instead put a #[CLI\Bootstrap(DrupalBootLevels::NONE)] Attribute on the command class and inject dependencies via the usual __construct() and AutowireTrait.

Note also that Drush commands packaged with Drupal modules are not discovered until after Drupal bootstraps, and therefore cannot use createEarly(). This mechanism is only usable by PSR-4 discovered commands packaged with Composer projects that are not Drupal modules.

Inflection

A command class may implement the following interfaces. When doing so, implement the corresponding trait to satisfy the interface.


Last update: October 24, 2024