让我们来看一个场景,其中发送了一个订单,并且可以根据 Order 类中的属性选择向客户发送一封邮件。发送电子邮件的功能位于“EmailService”服务中。我的问题是 Order.Dispatch 方法应该调用 EmailService 以根据 Order 类中的属性发送电子邮件,还是应该调用 Order.Dispatch 方法后的应用程序层调用 EmailService?在 DDD 中执行此操作的正确方法是什么?
谢谢你。神经网络
让我们来看一个场景,其中发送了一个订单,并且可以根据 Order 类中的属性选择向客户发送一封邮件。发送电子邮件的功能位于“EmailService”服务中。我的问题是 Order.Dispatch 方法应该调用 EmailService 以根据 Order 类中的属性发送电子邮件,还是应该调用 Order.Dispatch 方法后的应用程序层调用 EmailService?在 DDD 中执行此操作的正确方法是什么?
谢谢你。神经网络
领域事件允许您解耦关注点。一旦订单被发送,它就会引发一个域事件来通知感兴趣的订阅者。这使您可以决定将电子邮件发送到其他地方,以便订单聚合可以保持纯净。它通常还有助于更好地捕捉语言;发送订单后,发送电子邮件。
public class Order
{
public Order(string id)
{
Guard.ForEmpty(id, "id");
Id = id;
}
public string Id { get; private set; }
public void Dispatch()
{
DomainEvents.Raise(new OrderDispatchedEvent());
}
}
public class MailService : IHandle<OrderDispatchedEvents>
{
private readonly IMailSender _mailSender:
public MailService(IMailSender mailSender)
{
_mailSender = mailSender;
}
public void Handle(OrderDispatchedEvent @event)
{
_mailSender.Send(...);
}
}
DDD 不是食谱,因此没有正确的方法来做某事。
如果通过 Dispatch 表示订单正在送达客户的途中(提示:这里可能需要更准确的语义),那么将 Order 状态设置为 Dispatched 的应用程序层也可以要求 NotificationService 通知客户。
我相信域事件方法是最好的,所以一旦订单被发送,OrderDispatched 事件将被发布,通知服务可以订阅它,并使用 EmailService、SMSService 等通知客户
但是命令本身与此无关。其他一些域对象决定何时应分派 Order,它将 DispatchOrder 命令发送到将执行分派的域服务,然后它将生成 OrderDispatched 事件。这意味着您的 Order 不应该有 Dispatch 方法,因为它不是进行调度的 Order。一个简单的 Status 属性就足够了。
我会将其保留在应用程序服务层上。发送位可能很简单,Order.Dispatch
因为您可以传入服务实例,但首先编写电子邮件怎么样?这可能有点棘手。
将其放置在某些应用服务层任务的操作脚本中是一种方法。您还可以响应域事件(OrderDispatched
例如)然后发送。另一种选择(当使用服务总线时)是发布OrderDispatchedEvent
并让您订购端点订阅它,然后发送SendEMailCommand
到电子邮件端点。
但我不会尝试在域本身中处理发送,因为它感觉更像是输出生成,而不是域通常涉及的某些业务操作/计算。这是一项业务需求,但只是在另一个层面上,报告的工作方式相同。尽管与业务相关,或与流程相关,但它不一定属于域。
只是我的 ZAR 0.02 :)