mcpField
D
drupal-services

drupal-services

github.com/edutrulDevelopment7351 installsUpdated 21w ago
Repository

About drupal-services

A Drupal services and dependency-injection reference for developers implementing classes, controllers, forms, and plugins. It emphasizes constructor injection and includes service definitions, common service IDs, and Drush generation.

Key features

  1. 01Constructor dependency injection patterns
  2. 02Controller and form examples
  3. 03Plugin injection examples
  4. 04`services.yml` definitions
  5. 05Common Drupal service IDs
  6. 06Drush service generation

Use cases

  1. 01Replacing static service access in classes
  2. 02Wiring services into controllers and forms
  3. 03Injecting dependencies into plugins
  4. 04Generating a service scaffold with Drush

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/edutrul/drupal-ai --skill drupal-services

After installing, type/drupal-servicesin Claude Code to confirm it loaded.

Bundled filesREADME.md

Details

From the project README

Drupal Services & Dependency Injection

Core Principle

Never use \Drupal::service() in classes — inject via constructor.

Dependency Injection Patterns

Controllers & Forms (ContainerInjectionInterface)
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

final class MyController implements ContainerInjectionInterface {
  public function __construct(
    private readonly AccountProxyInterface $currentUser,
    private readonly EntityTypeManagerInterface $entityTypeManager,
  ) {}

  public static function create(ContainerInterface $container): static {
    return new static(
      $container->get('current_user'),
      $container->get('entity_type.manager'),
    );
  }
}
Plugins (ContainerFactoryPluginInterface)
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;

final class MyBlock extends BlockBase implements ContainerFactoryPluginInterface {
  public function __construct(
    array $configuration,
    string $plugin_id,
    mixed $plugin_definition,
    private readonly EntityTypeManagerInterface $entityTypeManager,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

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

Service Definition (services.yml)

services:
  my_module.my_service:
    class: Drupal\my_module\Service\MyService
    arguments:
      - '@entity_type.manager'
      - '@current_user'
      - '@logger.factory'

  # With autowiring (Drupal 10.3+)
  Drupal\my_module\Hook\MyModuleHooks:
    autowire: true

Common Service IDs

Service IDInterface
entity_type.managerEntityTypeManagerInterface
current_userAccountProxyInterface
logger.factoryLoggerChannelFactoryInterface
databaseConnection
config.factoryConfigFactoryInterface
rendererRendererInterface
messengerMessengerInterface
date.formatterDateFormatterInterface
language_managerLanguageManagerInterface
path_alias.managerAliasManagerInterface
module_handlerModuleHandlerInterface
cache.defaultCacheBackendInterface

StringTranslationTrait

Add use StringTranslationTrait; to classes that need $this->t() without full DI of the translation service.

Generating Services with Drush

drush generate service --answers='{
  "module": "my_module",
  "service_name": "my_module.helper",
  "class": "HelperService",
  "services": ["entity_type.manager", "logger.factory"]
}'

Comments

Markdown supported