具有依赖于需要EntityManager的服务的EventListener的Symfony循环引用

时间:2016-12-06 18:27:22

标签: symfony doctrine-orm

为简单起见,我有一个服务' TenantContext',它在每个请求中从数据库中检索当前租户,因此需要EntityManager。

此外,我想在刷新发生之前自动将具有ManyToOne关系的所有实体与Tenant相关联,因此我实现了一个TenantListener,它将检测这些实体并进行关联(setTenant())。为此,TenantListener需要TenantContext。

这是我的services.yml

services:
    tenant.service.tenant_context:
        class: TenantBundle\Context\TenantContext
        arguments: [ "@doctrine.orm.entity_manager" ]

    tenant.event_listener.tenant_listener:
        class: TenantBundle\EventListener\TenantListener
        arguments: [ "@tenant.service.tenant_context" ]
        tags:
            - { name: doctrine.event_listener, event: preFlush }

此配置给出了循环引用错误:

  [Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException]
  Circular reference detected for service "doctrine.dbal.default_connection", path: "doctrine.dbal.default_connection".

如果我理解正确,可以将EntityListener标记为' doctrine.event_listener'我正在使Doctrine EntityManager依赖于TenantListener,它依赖于TenantContext,它依赖于Doctrine EntityManager等。

我查了一篇类似的帖子Symfony Circular Reference Exception for Doctrine onFlush Event Listener Service,但我的情况有些不同。 TenantContext除了TenantListener之外还以多种方式使用,我不能总是通过Doctrine EntityManager来获取当前租户。

我无法找到打破这个圈子的解决方案。 有人知道如何实现这个目标吗? 提前谢谢。

Jorgo

1 个答案:

答案 0 :(得分:2)

您可能不希望将EntityManager,而是将Doctrine注册表注入tenant.service.tenant_context服务:

services:
    tenant.service.tenant_context:
        class: TenantBundle\Context\TenantContext
        arguments: [ "@doctrine" ]

有关如何访问EntityManager课程中TenantBundle\Context\TenantContext个实例的示例:

namespace TenantBundle\Context

use Symfony\Bridge\Doctrine\RegistryInterface;

class TenantContext
{
    protected $doctrine;

    public function __construct(RegistryInterface $doctrine)
    {
        $this->doctrine = $doctrine;
    }

    public function getEntityManager()
    {
        return $this->doctrine->getEntityManager();
    } 
}