如何将容器/服务注入Symfony2中的Doctrine2实体


How to inject container/service to Doctrine2 entity in Symfony2?

我知道这个问题乍一看很可怕。

这就是我所拥有的:

我将模型的一部分存储在*.yaml文件中,并在需要时加载。让我们称之为StaticObject。它有10个左右的对象,无法按设计进行缩放,并且是只读的。每个StaticObject都有自己的ID,我可以从容器中的服务中获得给定ID的对象,比如:

$container->get('static_object_repository')->getById('foo');

现在我有了一个与StaticObject有"关联"的实体。我希望它作为ID存储在数据库中,所以我在实体中添加了新的字段$staticObjectId,如下所示:

class MyEntity
{
    //...
    /**
     * @ORM'Column(type="string", name="static_object_id")
     */
    protected $staticObjectId;
    //...
}

现在,每当我想从实体中获取StaticObject时,我都会从容器中调用服务,比如:

$staticObject = $container->get('static_object_repository')->getById($entity->getStaticObjectId());

当我想更改相关对象时,我会做一些类似的事情:

$entity->setStaticObjectId($staticObject->getId());

我希望你对我的代码有足够的了解。若我遗漏了一些对你们理解问题很重要的东西,请告诉我。

这就是我想要的:

我想将StaticObject实例直接存储在实体中,这样我就可以简单地获取和设置它

$entity->getStaticObject();
//and
$entity->setStaticObject($staticObject);

我的第一个想法是在getter和setter中隐藏所有需要的转换。所以我得到:

class MyEntity 
{
    //...
    public function setStaticObject(StaticObject $so)
    {
        $this->staticObjectId = $so->getId();
    }
    public function getStaticObject()
    {
        return $container->get('static_object_repository')->getById($this->staticObjectId);
    }
    //...
}

但是等等。。。我的模型中不能有容器。不是吗?我找不到如何将容器/服务注入实体。

我的第二个想法是使用自定义条令映射类型。再说一遍,您不能向它注入服务(因为自定义类型是类,没有对象/服务)。我做了Doctine2文档这一部分的所有内容,并在Symfony2食谱中阅读了这一部分,但我看不到解决方案。

我该怎么做?

您可以在prePersist、preUpdate。。。,然后通过服务配置将服务注入其中

文档非常棒

在实体关系离开ORM体系结构时,在它们到达日常应用层之前,通常最好构建实体关系。做到这一点的最佳方法是保持实体简单:

class MyEntity
{
    public function setStaticObject(StaticObject $so)
    {
        $this->staticObject = $so;
    }
    public function getStaticObject()
    {
        return $this->staticObject;
    }
}

并在加载行后使用自定义Hydrator设置StaticObject:

https://www.techpunch.co.uk/development/create-custom-doctrine2-hydrator-symfony2

如果延迟加载很重要,那么使用自定义水合来注入StaticObjectFactory类并不是一个很大的步骤,您可以这样使用它:

// MyEntity
public function getStaticObject()
{
    if (!isset($this->staticObject)) {
        $this->staticObject = $this->staticObjectFactory->loadById($this->getStaticObjectId());
    }
    return $this->staticObject
}

您应该做的是:

public function getStaticObject($staticObjectRepository)
{
    return $staticObjectRepository->getById($this->staticObjectId);
}

当然,你也可以搜索这个问题的其他答案。例如:在实体对象中注入或访问服务容器