Skip to main content
Home
Drupal life hacks

Main navigation

  • Drupal
  • React
  • WP
  • Contact
  • About
User account menu
  • Log in

Breadcrumb

  1. Home

Drupal 11.3: Simplifying Plugin Development with Autowired create() in PluginBase

By admin, 15 October, 2025

Drupal has always been flexible when it comes to plugins, but dependency injection in plugins has historically required boilerplate code. In Drupal 11.3, the PluginBase class introduces a game-changing feature: a generic create() factory method with autowired parameters. This update simplifies plugin development and reduces repetitive code.


The Old Way: Writing create() Manually

Before Drupal 11.3, if you wanted to inject services into a plugin, you needed two things:

  1. A constructor that accepted services.
  2. A static create() method to fetch services from the container.

Here’s an example of a block plugin that uses the entity_type.manager service:

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;

class MyBlock extends BlockBase implements ContainerFactoryPluginInterface {

  protected $entityTypeManager;

  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
  }

  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager')
    );
  }
}

As you can see, we needed both the constructor and the create() method to inject the service. This pattern was repeated across almost every plugin that needed dependencies.


The New Way: Autowired create()

With Drupal 11.3, you can skip writing the create() method entirely. Instead, you use PHP 8 attributes (#[Autowire]) directly in the constructor:

use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

class MyBlock extends PluginBase {

  protected $entityTypeManager;

  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    #[Autowire(service: 'entity_type.manager')]
    EntityTypeManagerInterface $entity_type_manager
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
  }
}

✅ That’s it. No static create() method required. Drupal automatically injects the service.


Autowiring Without Attributes

If the service can be inferred directly from the type hint (interface name), you don’t even need #[Autowire]:

public function __construct(
  array $configuration,
  $plugin_id,
  $plugin_definition,
  EntityTypeManagerInterface $entity_type_manager
) {
  parent::__construct($configuration, $plugin_id, $plugin_definition);
  $this->entityTypeManager = $entity_type_manager;
}

If Drupal can’t determine the service automatically, it will throw an exception, prompting you to add the #[Autowire] attribute.


Benefits

  • Less boilerplate: No more writing repetitive create() methods.
  • Clearer constructor: Dependencies are visible and type-hinted.
  • Automatic service injection: Saves time and reduces errors.
  • Modern PHP: Uses PHP 8 attributes, aligning Drupal with modern PHP practices.

When to Use

  • Any plugin that extends PluginBase.
  • When using services from the container.
  • PHP 8 is required for the attribute syntax.

Conclusion

Drupal 11.3’s autowired create() in PluginBase is a small but impactful improvement. It simplifies plugin development, reduces boilerplate, and encourages modern PHP practices. For any module developer, it’s a welcome change that makes dependency injection easier and cleaner. 

Tags

  • #Drupal Planet
  • Plugin Development
  • PluginBase

Comments

About text formats

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Powered by Drupal