从域服务中刷新EntityManager是否可以?

时间:2013-04-02 09:15:21

标签: orm domain-driven-design entitymanager domainservices

我有一个名为OrderService的域名服务,使用saveOrder()方法:

class OrderService
{
    // ...

    public function saveOrder(Order $order)
    {
        $this->orderRepository->add($order);
        // $this->entityManager->flush();

        $this->notificationService->notifyOrderPlaced($order);
    }
}

saveOrder()将订单添加到存储库(内部调用EntityManager上的persist()),然后将订单传递给NotificationService以发送适当的通知(电子邮件,SMS)。

问题是,虽然NotificationService需要订单ID包含在通知中,但订单还没有ID,因为它没有持久保存到DB(ID是自动生成的)。

显而易见的解决方案似乎将EntityManager作为依赖关系传递给OrderService,并在flush()方法之后立即传递add(),如上例所示。但我一直不愿意让域服务知道EntityManager,而是让他们只与存储库或其他服务交谈。

  • 依赖于EntityManager的域服务有哪些缺点(如果有的话)?
  • 有更好的选择吗?

注意:我正在使用PHP和Doctrine ORM,但我相信相同的原则适用于Java& Hibernate也是。

1 个答案:

答案 0 :(得分:0)

您可能需要考虑其中一个选项(或两者)

  • 使此服务成为应用层服务而非域服务。在应用程序服务中调用更改跟踪器是完全可以的,因为它应该知道应用程序上下文和当前用例的进度。典型的应用程序服务将提交业务事务/要求更改跟踪器在完成后保存更改,所以why not call it to generate Id's也是如此?

    如果您担心数据库涉及用例的中间,也许您可​​以找到NHibernate的Guid.Comb strategy的等价物,以使您的ORM生成Id而无需立即向数据库发出INSERT

  • 使用域事件。在创建之后,一个命令可以告知世界它已经被新建了。通知服务将处理该事件并发送适当的通知。您将找到here的示例(它还包括用于处理业务事务的应用程序层服务)。