【发布时间】:2017-02-07 17:56:34
【问题描述】:
为了重构有关工单通知系统的代码,我创建了一个 Doctrine 监听器:
final class TicketNotificationListener implements EventSubscriber
{
/**
* @var TicketMailer
*/
private $mailer;
/**
* @var TicketSlackSender
*/
private $slackSender;
/**
* @var NotificationManager
*/
private $notificationManager;
/**
* We must wait the flush to send closing notification in order to
* be sure to have the latest message of the ticket.
*
* @var Ticket[]|ArrayCollection
*/
private $closedTickets;
/**
* @param TicketMailer $mailer
* @param TicketSlackSender $slackSender
* @param NotificationManager $notificationManager
*/
public function __construct(TicketMailer $mailer, TicketSlackSender $slackSender, NotificationManager $notificationManager)
{
$this->mailer = $mailer;
$this->slackSender = $slackSender;
$this->notificationManager = $notificationManager;
$this->closedTickets = new ArrayCollection();
}
// Stuff...
}
目标是使用 Doctrine SQL 在通过邮件、Slack 和内部通知创建或更新 Ticket 或 TicketMessage 实体时发送通知。
我已经遇到了 Doctrine 的循环依赖问题,所以我从事件 args 中注入了实体管理器:
class NotificationManager
{
/**
* Must be set instead of extending the EntityManagerDecorator class to avoid circular dependency.
*
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var NotificationRepository
*/
private $notificationRepository;
/**
* @var RouterInterface
*/
private $router;
/**
* @param RouterInterface $router
*/
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
/**
* @param EntityManagerInterface $entityManager
*/
public function setEntityManager(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
$this->notificationRepository = $this->entityManager->getRepository('AppBundle:Notification');
}
// Stuff...
}
经理从TicketNotificationListener注入
public function postPersist(LifecycleEventArgs $args)
{
// Must be lazy set from here to avoid circular dependency.
$this->notificationManager->setEntityManager($args->getEntityManager());
$entity = $args->getEntity();
}
Web 应用程序正在运行,但是当我尝试运行像 doctrine:database:drop 这样的命令时,我得到了这个:
[Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException]
Circular reference detected for service "doctrine.dbal.default_connection", path: "doctrine.dbal.default_connection -> mailer.ticket -> twig -> security.authorization_checker -> security.authentication.manager -> fos_user.user_provider.username_email -> fos_user.user_manager".
但这与供应商服务有关。
如何解决这个问题?为什么我只在 cli 上出现此错误?
谢谢。
【问题讨论】:
-
您是否在不同的环境中运行 cli 和 web?例如。控制台 --env dev 和 web 正在访问 app.php?如果是,请手动清除缓存,然后重试。
-
错误消息有点暗示 TicketMailer 是问题所在。它与数据库有任何连接吗?
-
Vladmir: 相同的环境并且已经删除了缓存,这没有任何改变。
-
Cerad:TicketMailer 对 twig 有依赖关系,它对身份验证管理器有依赖关系,而对 fos_user 管理器有依赖关系,它对...学说连接有依赖关系! \o/ 但如果邮件程序是问题所在,我会感到惊讶。添加 NotificationManager 后出现此错误...
-
我无法解释为什么您没有在您的网络中看到这一点,但原则实体管理器服务依赖于它的所有侦听器。就像 Symfony 实现事物的方式一样。因此,您的票据原则侦听器不能依赖于使用原则实体管理器或连接的任何内容。只需要重新考虑您的依赖关系,或者可能手动将您的学说侦听器添加到实体管理器中,而不是对其进行标记。您可能会逃脱 TicketMailer::setAuthenticationManager 但正如您所看到的,事情开始变得混乱和混乱。
标签: php symfony dependency-injection doctrine-orm