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
- 01Constructor dependency injection patterns
- 02Controller and form examples
- 03Plugin injection examples
- 04`services.yml` definitions
- 05Common Drupal service IDs
- 06Drush service generation
Use cases
- 01Replacing static service access in classes
- 02Wiring services into controllers and forms
- 03Injecting dependencies into plugins
- 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-servicesAfter installing, type/drupal-servicesin Claude Code to confirm it loaded.
Bundled filesREADME.md
Details
From the project READMEDrupal 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 ID | Interface |
|---|---|
entity_type.manager | EntityTypeManagerInterface |
current_user | AccountProxyInterface |
logger.factory | LoggerChannelFactoryInterface |
database | Connection |
config.factory | ConfigFactoryInterface |
renderer | RendererInterface |
messenger | MessengerInterface |
date.formatter | DateFormatterInterface |
language_manager | LanguageManagerInterface |
path_alias.manager | AliasManagerInterface |
module_handler | ModuleHandlerInterface |
cache.default | CacheBackendInterface |
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