如何在Symfony2中向Doctrine2实体注入容器/服务?

时间:2014-09-14 16:21:35

标签: php symfony doctrine-orm

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

这就是我所拥有的:

我的部分模型存储在* .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时,我都会从容器中调用service,如:

$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);
    }

    //...
}

但是等等......我的模型中没有容器。不是吗?我无处可寻找如何向实体注入容器/服务。

我的第二个想法是使用自定义Doctrine映射类型。再次 - 你不能注入服务(因为自定义类型是类,没有对象/服务)。我做了everything from this section of Doctine2 documentationi read this section in Symfony2 cookbook,但我看不到解决方案。

我该怎么做?

3 个答案:

答案 0 :(得分:2)

你可以在prePersist,preUpdate,...上设置一个监听器,然后通过服务配置将服务注入其中

the docs are awesome

答案 1 :(得分:2)

在离开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

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

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

    return $this->staticObject
}

答案 2 :(得分:0)

你应该做的是:

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

当然,您也可以搜索此问题的其他答案。例如:Injectiong or accessing service container within an entity object