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

Symfony 4.4依赖注入:标记迭代器自动配置问题求助

Symfony Dependency Injection 4.4 问题解决

一、解决 TaggedIteratorArgument 传入数组的问题

你当前代码里把 TaggedIteratorArgument 包裹在数组中传给 type_loader,导致参数变成了包含 RewindableGenerator 的数组。正确做法是直接传入 TaggedIteratorArgument,无需数组包裹:

public function load(array $configs, ContainerBuilder $container)
{
    // 自动为所有实现 NamedType 的服务打标签并设置懒加载
    $container->registerForAutoconfiguration(NamedType::class)
        ->addTag('type')
        ->setLazy(true);

    // 直接传入 TaggedIteratorArgument,而非数组包裹
    $container->autowire('type_loader', TypeLoader::class)
        ->addArgument(new TaggedIteratorArgument('type'));
}

在 TypeLoader 的构造函数中,将参数声明为 iterable 类型即可直接遍历(RewindableGenerator 本身是可迭代对象):

class TypeLoader
{
    private $types;

    public function __construct(iterable $types)
    {
        $this->types = $types;
    }

    public function process()
    {
        foreach ($this->types as $type) {
            // 处理每个类型服务
        }
    }
}

二、用 PHP 代码实现指定 YAML 配置的效果

要实现你给出的 YAML 配置(加载指定目录下的所有类作为服务,自动装配、自动配置、公开并打标签),可以通过以下两种方式完成:

方式一:使用批量注册方法

public function load(array $configs, ContainerBuilder $container)
{
    // 设置服务默认参数
    $defaults = new Definition();
    $defaults->setAutowired(true);
    $defaults->setAutoconfigured(true);
    $defaults->setPublic(true);

    // 批量注册指定目录下的所有类作为服务,并统一打标签
    $container->registerClasses(
        $defaults,
        'Project\\Framework\\Endpoint\\Type\\',
        '../../Endpoint/Type/*'
    )->addTag('endpoint_type');
}

方式二:手动扫描目录注册(更精细控制)

use Symfony\Component\Finder\Finder;
use Symfony\Component\DependencyInjection\Definition;

public function load(array $configs, ContainerBuilder $container)
{
    $finder = new Finder();
    $finder->files()->in(__DIR__ . '/../../Endpoint/Type')->name('*.php');

    foreach ($finder as $file) {
        // 解析类的命名空间与类名
        $namespace = 'Project\\Framework\\Endpoint\\Type';
        $className = $namespace . '\\' . $file->getBasename('.php');

        // 创建服务定义并配置参数
        $definition = new Definition($className);
        $definition->setAutowired(true);
        $definition->setAutoconfigured(true);
        $definition->setPublic(true);
        $definition->addTag('endpoint_type');

        // 将服务注册到容器(默认服务ID为类全名)
        $container->setDefinition($className, $definition);
    }
}

注意:使用 Finder 需要确保已安装 symfony/finder 组件(Symfony 4.4 通常默认包含,若缺失可手动安装)。


内容的提问来源于stack exchange,提问作者Thomas DELAPORTE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:00:35