Symfony:如何获得所有服务及其各自的课程

时间:2015-10-30 19:25:36

标签: php symfony dependency-injection

我想要实现的目标如下:我的应用程序中的某些服务带有特殊注释。稍后,在构建过程中,特殊命令应该找到带有该注释的所有文件。

我的方法是首先加载所有包:

$container = $this->getContainer();

foreach ($container->getParameter('kernel.bundles') as $alias => $namespace)
    $bundle = $container->get('kernel')->getBundle($alias);

我在这一点上陷入困​​境。如何让$bundle实例告诉我它的服务?

注意:我也对非特定于捆绑的解决方案感到满意,即加载所有可用服务定义的解决方案。 ContainerBuildergetDefinitions看起来很有希望,虽然我不知道如何从命令中访问它。

我需要获取一个包含服务ID及其类的列表 - 尤其是类,因为这些是我需要加载到注释阅读器中的。

显然,我不想自己解析services.yml,而且我也想避免从$container->getServiceIds()加载每个服务的实例。

(顺便说一句,tagged services无济于事;我需要注释。我想自动检测带注释的服务,因为标记它们需要额外的步骤,这是不必要的,容易出错。)

2 个答案:

答案 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);

    // ...
}