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
相关产品推荐
相关产品推荐

