标题很好地解释了这个问题。我在Doctrine Entity类的生命周期回调中,想做一些额外的DB条目。为此,我需要获得内核的一个实例。我该怎么做?
大多数时候都需要实体中的容器/内核,这是错误的。实体不应该知道任何服务。为什么?
基本上,实体是一个表示事物的对象。实体主要用于关系数据库,但您可以随时将此实体用于其他事务(序列化它,从HTTP层安装它…)。
你希望你的实体是可单元测试的,这意味着你需要能够轻松地安装你的实体,而不需要任何东西,主要是没有任何业务逻辑。
您应该将您的逻辑移动到另一层,即将实例化您的实体的层
对于您的用例,我认为,最简单的方法是使用条令事件。
服务。yml
services:
acme_foo.bar_listener:
class: Acme'FooBundle'Bar'BarListener
arguments:
- @kernel
tags:
- { name: doctrine.event_listener, event: postLoad }
Acme''FooBundle''Bar''BarListener
use Symfony'Component'HttpKernel'KernelInterface;
use Doctrine'ORM'Event'LifecycleEventArgs;
use Acme'FooBundle'Entity'Bar;
class BarListener
{
protected $kernel;
/**
* Constructor
*
* @param KernelInterface $kernel A kernel instance
*/
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* On Post Load
* This method will be trigerred once an entity gets loaded
*
* @param LifecycleEventArgs $args Doctrine event
*/
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!($entity instanceof Bar)) {
return;
}
$entity->setEnvironment($this->kernel->getEnvironment());
}
}
这样,您的实体就可以保持平坦,没有依赖关系,并且可以轻松地对事件侦听器进行单元测试
- 如果必须使用某些服务,则不应该特别使用整个容器或内核实例
- 使用服务本身-始终尝试注入单个服务,而不是整个容器
- 你的案例看起来应该使用条令事件