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+.

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 determine the 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: LoginCommands).

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\ContanierInterface 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+

The createEarly() method was deprecated in Drush 12.5. Instead put a #[CLI\Bootstrap(DrupalBootLevels::NONE)] Attribute on the command class and inject dependencies via the usual __construct with 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: March 20, 2024