You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony中命令调度模式下如何为自定义Handler自动注入依赖服务

实现方案

你需要借助Symfony的依赖注入容器能力替换掉手动new实例的逻辑,有两种常用实现方式:


方案1:直接使用全局服务容器

修改HandlerResolver,注入Symfony的全局容器,由容器负责创建Handler实例,自动解析注入构造参数依赖:

<?php

use Psr\Container\ContainerInterface;

class HandlerResolver
{
    public function __construct(
        private ContainerInterface $container
    ) {
    }

    public function resolve(CommandInterface $command): AbstractHandler
    {
        $handlerClass = preg_replace('/Command/', 'Handler', $command::class);
        // 容器会自动解析构造参数的类型提示,注入已声明的对应服务
        return $this->container->get($handlerClass);
    }
}

注意:该方案需要将所有Handler类配置为容器可访问的服务,如果你开启了默认的autowire/autoconfigure,只需要在config/services.yaml中添加配置将Handler标记为公共服务即可:

services:
    App\Handler\:
        resource: '../src/Handler/*'
        public: true

方案2:使用专属服务定位器(更符合Symfony最佳实践)

该方案不会将Handler暴露到全局公共服务列表,权限管控更合理:

  1. 先新增一个标记接口,用于识别所有Handler类
<?php
// 放在你自己的接口目录下即可
interface CommandHandlerInterface
{
}
  1. 让抽象Handler实现该标记接口
abstract class AbstractHandler implements CommandHandlerInterface
{
    // 原有代码无需修改
}
  1. 修改config/services.yaml配置,给所有Handler打标签并创建专属服务定位器
services:
    # 自动加载所有Handler,开启自动注入
    App\Handler\:
        resource: '../src/Handler/*'
        autowire: true
        autoconfigure: true

    # 给所有实现标记接口的类自动打标签
    _instanceof:
        App\Contract\CommandHandlerInterface:
            tags: ['app.command_handler']

    # 为HandlerResolver注入专属服务定位器,包含所有打了标签的Handler
    App\Resolver\HandlerResolver:
        arguments:
            $handlerLocator: !tagged_locator { tag: 'app.command_handler' }
  1. 修改HandlerResolver代码,使用专属定位器获取Handler实例
<?php

use Psr\Container\ContainerInterface;

class HandlerResolver
{
    public function __construct(
        // 注入的是只包含所有Handler的专属定位器
        private ContainerInterface $handlerLocator
    ) {
    }

    public function resolve(CommandInterface $command): AbstractHandler
    {
        $handlerClass = preg_replace('/Command/', 'Handler', $command::class);
        return $this->handlerLocator->get($handlerClass);
    }
}

注意事项

只要你开启了Symfony默认的autowire配置,所有Handler构造函数中类型声明的服务,Symfony都会自动匹配注入,不需要额外手动配置。如果Handler有非服务类型的构造参数,可以在services.yaml中对应Handler的配置条目下手动指定参数值即可。

内容的提问来源于stack exchange,提问作者Baptiste Vadé

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 16:54:05