我想要实现的目标如下:我的应用程序中的某些服务带有特殊注释。稍后,在构建过程中,特殊命令应该找到带有该注释的所有文件。
我的方法是首先加载所有包:
$container = $this->getContainer();
foreach ($container->getParameter('kernel.bundles') as $alias => $namespace)
$bundle = $container->get('kernel')->getBundle($alias);
我在这一点上陷入困境。如何让$bundle
实例告诉我它的服务?
注意:我也对非特定于捆绑的解决方案感到满意,即加载所有可用服务定义的解决方案。 ContainerBuilder
有getDefinitions
看起来很有希望,虽然我不知道如何从命令中访问它。
我需要获取一个包含服务ID及其类的列表 - 尤其是类,因为这些是我需要加载到注释阅读器中的。
显然,我不想自己解析services.yml
,而且我也想避免从$container->getServiceIds()
加载每个服务的实例。
(顺便说一句,tagged services无济于事;我需要注释。我想自动检测带注释的服务,因为标记它们需要额外的步骤,这是不必要的,容易出错。)
答案 0 :(得分:3)
编译器传递仍然可以。但是,不是找到标记服务,而是获得所有定义。这样做的好处是可以使用定义,而不是实例化每个服务。
当然,您需要创建一个管理器类,它接受保存所有类名,以便稍后在命令中使用它。
<?php
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
class RegisterClassNamesPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->has('app.class_names_manager')) {
return;
}
$manager = $container->findDefinition(
'app.class_names_manager'
);
foreach ($container->getDefinitions() as $id => $definition) {
$class = $container->getParameterBag()->resolveValue($def->getClass());
$definition->addMethodCall(
'addClassName',
array($id, $class)
);
}
}
}
答案 1 :(得分:2)
好的,我现在通过getServiceIds
加载所有服务的不太优雅的方法解决了这个问题:
$container = $this->getContainer();
foreach ($container->getServiceIds() as $id)
{
$service = $container->get($id, $container::IGNORE_ON_INVALID_REFERENCE);
if (!$service) continue;
$class = get_class($service);
// ...
}