【问题标题】:How to inject shared service from compiler pass in Symfony如何从 Symfony 中的编译器传递注入共享服务
【发布时间】:2017-09-08 12:18:40
【问题描述】:

我正在尝试通过旨在替换 FOSRestBundle 中的一项服务的编译器传递来注入令牌存储服务:

<?php

namespace App\Compiler;

use App\Event\Listener\RestParamConverter;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class RestParamConverterOverride implements CompilerPassInterface
{
    /**
     * You can modify the container here before it is dumped to PHP code.
     *
     * @param ContainerBuilder $container
     */
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('fos_rest.converter.request_body');
        $definition->setClass(RestParamConverter::class);
        $definition->addArgument($container->getDefinition('security.token_storage'));
    }
}

由于某种原因,即使安全系统在TokenStorage 中正确设置了令牌,但在我的自定义服务中,当我访问TokenStorage 时,$tokenStorage-&gt;getToken() 似乎返回null。在我尝试检索值之前,我已经调试了代码并确保身份验证正在运行。

我已经对其他服务进行了测试,并且我看到了无论我用$definition-&gt;addArgument($container-&gt;getDefinition(SERVICE_HERE)); 注入的行为。这很奇怪,但在编译器传递中,它似乎创建了该服务的新实例,而不是使用共享服务。

在其他部分,服务注入工作正常——只是在这些编译器通道中没有。谁能解释一下为什么会这样?

【问题讨论】:

  • 可以查看缓存目录下生成的容器,看看是怎么回事。这至少会证实(或否认)你对共享服务的怀疑。
  • @Cerad:是的,似乎是newed,而不是使用共享服务。
  • 我在通行证和动态修改服务定义方面做得不多。但是作为一个在黑暗中的镜头,您是否尝试过 ->addArgument(new Reference('service_name'))
  • @Cerad:太棒了,它奏效了。非常感谢!如果您将其添加为答案,我会接受。

标签: symfony dependency-injection


【解决方案1】:

文档展示了如何注入对现有服务的引用,而不是创建服务的新实例:https://symfony.com/doc/current/components/dependency_injection.html#basic-usage

具体来说,使用:

$definition->addArgument(new Reference('service_name'))

【讨论】:

    猜你喜欢
    • 2022-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 2017-03-01
    相关资源
    最近更新 更多