将安全上下文注入(实体侦听器)类时的循环引用

时间:2012-01-03 06:44:15

标签: symfony dependency-injection

这里有两个问题,说注入整个服务容器应该解决这个问题。但问题是......见下文(注意尝试2和3之间的区别)......

尝试1

public function __construct(SecurityContext $securityContext) {
    $this->securityContext = $securityContext);  
}  

Curcular Reference。 好的......

尝试2

public function __construct(ContainerInterface $container) {
    $this->securityContext = $container->get('security.context');  
}  

循环引用(为什么?,我在try 3中注入容器,只是我得到了安全上下文)

尝试3

public function __construct(ContainerInterface $container) {
    $this->container = $container;  
}  

作品。

3 个答案:

答案 0 :(得分:25)

这是因为您的安全上下文依赖于此侦听器,可能是通过将实体管理器注入到用户提供程序中。最好的解决方案是将容器注入侦听器并懒惰地访问安全上下文。

我通常不喜欢将整个容器注入服务,但是使用Doctrine侦听器会产生异常,因为它们会被急切地加载,因此应该尽可能地保持懒惰。

答案 1 :(得分:8)

从Symfony 2.6开始,这个问题应该修复。拉取请求刚刚被主人接受。您的问题在此处描述。 https://github.com/symfony/symfony/pull/11690

从Symfony 2.6开始,您可以将security.token_storage注入您的监听器。此服务将包含SecurityContext在< = 2.5中使用的令牌。在3.0中,此服务将完全替换SecurityContext::getToken()。您可以在此处查看基本更改列表:http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements#deprecated-the-security-context-service

2.6中的用法示例:

您的配置:

services:
    my.listener:
        class: EntityListener
        arguments:
            - "@security.token_storage"
        tags:
            - { name: doctrine.event_listener, event: prePersist }


您的听众

use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class EntityListener
{
    private $token_storage;

    public function __construct(TokenStorageInterface $token_storage)
    {
        $this->token_storage = $token_storage;
    }

    public function prePersist(LifeCycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $entity->setCreatedBy($this->token_storage->getToken()->getUsername());
    }
}

答案 2 :(得分:1)

您应该始终尽量避免将容器直接注入您的服务。

我认为“循环引用”问题以及可能的性能问题的最佳解决方案是使用从Symfony 2.3开始提供的«Lazy Services»功能。

在服务容器配置中将依赖项标记为lazy并安装ProxyManager Bridge(查看上面的Lazy Services文档中的详细信息)。

我希望有所帮助,欢呼。