我有一个名为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,而是让他们只与存储库或其他服务交谈。
注意:我正在使用PHP和Doctrine ORM,但我相信相同的原则适用于Java& Hibernate也是。
答案 0 :(得分:0)
您可能需要考虑其中一个选项(或两者)
使此服务成为应用层服务而非域服务。在应用程序服务中调用更改跟踪器是完全可以的,因为它应该知道应用程序上下文和当前用例的进度。典型的应用程序服务将提交业务事务/要求更改跟踪器在完成后保存更改,所以why not call it to generate Id's也是如此?
如果您担心数据库涉及用例的中间,也许您可以找到NHibernate的Guid.Comb strategy的等价物,以使您的ORM生成Id而无需立即向数据库发出INSERT
使用域事件。在创建之后,一个命令可以告知世界它已经被新建了。通知服务将处理该事件并发送适当的通知。您将找到here的示例(它还包括用于处理业务事务的应用程序层服务)。