我正在努力解决以下问题:
我为我的一个实体创建了一个 EntityListener。
namespace App\Event\EventListener\Vendor;
use App\Entity\Vendor;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\Messenger\MessageBusInterface;
class VendorListener
{
private MessageBusInterface $messageBus;
public function __construct(MessageBusInterface $messageBus)
{
$this->messageBus = $messageBus;
}
public function preUpdate(
Vendor $vendor,
PreUpdateEventArgs $args,
) {
if ($args->hasChangedField('blacklistStatus')) {
if ($args->getNewValue('blacklistStatus')) {
//do something
}
}
}
}
在尊重实体中,我通过注释“附加”了它。
<?php
namespace App\Entity;
use App\Event\EventListener\Vendor\VendorListener;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: VendorRepository::class)]
#[ORM\EntityListeners([VendorListener::class])]
class Vendor
{
...
}
我的 service.yaml 文件如下所示,如官方 docs 中所述。
App\Event\EventListener\Vendor\VendorListener:
tags:
-
name: doctrine.orm.entity_listener
entity: App\Entity\Vendor
event: preUpdate
监听器工作并按预期触发,但只要我注释掉构造方法。 如果我尝试通过构造函数访问 EntityListener 中的某些服务,我会显示以下错误消息:
函数 App\Event\EventListener\Vendor\VendorListener::__construct() 的参数太少,在第 82 行 C:\Users\Admin\Desktop odensee endor\doctrine\doctrine-bundle\Mapping\ContainerEntityListenerResolver.php 中传递了 0正好是 1 个预期
我错过了什么吗?或者现在是否可以将服务自动连接到学说实体监听器中,因为出于某种原因它们不是由 symfony 启动的,而是由学说启动的?
我发现了一个有趣的 thread 谈论我遇到的问题。遗憾的是,建议的解决方案不起作用。
#[ORM\EntityListeners([VendorListener::class])]
这是 doctrine 监听器,不是 symfony 监听器。 Autowire 仅适用于 symfony 监听器。
您可以创建一个实现
Doctrine\Common\EventSubscriber
的侦听器。没有service.yaml
配置和实体注释ORM\EntityListeners
.VendorListener
namespace App\EventListener\Doctrine;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;
use Symfony\Component\Messenger\MessageBusInterface;
class VendorListener implements EventSubscriber
{
private MessageBusInterface $messageBus;
public function __construct(MessageBusInterface $messageBus)
{
$this->messageBus = $messageBus;
}
public function preUpdate(PreUpdateEventArgs $args)
{
if (!$args->getObject() instanceof Vendor) {
return;
}
if ($args->hasChangedField('blacklistStatus')) {
if ($args->getNewValue('blacklistStatus')) {
//do something
}
}
}
public function getSubscribedEvents(): array
{
return [
Events::preUpdate => 'preUpdate',
];
}
}
以下解决方案现在对我有效:
而不是通过注释将 EntityListener 附加到相应的实体,例如
#[ORM\Entity(repositoryClass: VendorRepository::class)]
#[ORM\EntityListeners([VendorListener::class])]
class Vendor
{
...
}
在 EntityListener 本身中配置目标实体,如此处所述
use App\Entity\Vendor;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;
use Symfony\Component\Messenger\MessageBusInterface;
#[AsEntityListener(event: Events::preUpdate, method: 'preUpdate', entity: Vendor::class)]
class VendorListener
{
...
}
有了这个,通过构造函数的依赖注入是可能的。原因似乎是
ORM\EntityListeners()
由学说本身处理,这使它们无法访问容器。