用途
本技能用于指导 Drupal 10/11 模块开发中的服务定义、依赖注入(DI)与接口设计,并给出应避免的反模式。适用于创建服务、注册依赖、编写插件等场景。
主要能力
- 服务定义:在
my_module.services.yml中声明服务的class、arguments(以@引用其他服务)和tags(如event_subscriber)。 - 构造器注入与属性提升:示例类
ContentManager通过private readonly构造参数注入EntityTypeManagerInterface、AccountProxyInterface、LoggerInterface。 - 接口设计:定义
ContentManagerInterface,并在实现类上标注implements。 - 插件依赖注入:Block 插件实现
ContainerFactoryPluginInterface,在静态create()中从容器取得my_module.content_manager。 - 反模式说明:禁止在类中使用
\Drupal::entityTypeManager()等静态调用,应改用注入依赖;禁止用具体类做类型提示,应改用接口。 - 服务名称发现:服务名没有统一命名约定,不要猜测,用
ddev drush eval 'print json_encode(["exists" => Drupal::hasService("module_name.service_name")]);'验证;失败时直接阅读模块的*.services.yml,注意前缀可能是单数(如group_permission.checker)。 - 定位实际加载文件:当模块同时存在于
vendor/drupal/与web/modules/contrib/时,用ReflectionMethod的getFileName()确认运行时加载的是哪个文件,并编辑该文件(常见于 Composer 补丁模块)。
使用方式
按示例编写 .services.yml、接口与实现类;在插件中实现容器工厂接口;用上述 drush 命令核查服务名;用反射定位被补丁模块的实际文件。
适用场景
Drupal 模块的服务注册、事件订阅器、插件开发,以及服务名排查与补丁文件加载问题定位。
限制
资料未提供支持的 Drupal 具体小版本范围、安装步骤、收费或效果说明;示例代码需按实际模块结构调整。