在我的域中,服务用于协调涉及多个聚合和/或其他服务的更高级别行为。例如,订单管理系统在取消订单时需要执行以下步骤:
对此进行编码非常简单,除了我必须实现的一些其他问题:
仅当步骤1,2和4成功时,操作才会成功。因此,我不能将这些步骤实现为事件处理程序。
暂停使用持久性机制的任何问题(它就是这样),您能否帮助我了解如何最好地实施我的服务,以便它正确处理验证,错误和管理订单状态?
(我应该注意到我没有使用Event Sourcing,所以不要让OrderCanceledEvent抛弃你。)
答案 0 :(得分:1)
使用事件处理程序解决此问题的一种方法是使用saga。工作流程如下:
CancelOrder
命令后,系统会启动OrderCancellationSaga
,将订单置于Cancelling
状态。OrderCancelled
事件。在此方案中,审核可以在任何阶段进行。此外,应该在开始传奇之前验证权限以及是否可以首先取消订单,或者作为启动传奇的第一步。
使用C#和NServiceBus sagas的粗略样本:
class OrderOrderCancellationSaga : Saga<OrderCancellationSagaData>
,IAmStartedBy<CancelOrderCommand>,
,IHandle<PaymentGatewayInteractionFailedEvent>
{
public OrderService OrderService { get; set; }
public PaymentGateway PaymentGateway { get; set; }
// correlate saga messages by order ID
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<PaymentGatewayInteractionFailedEvent>(x => x.OrderId, x =>x.OrderId);
ConfigureMapping<RefundCompletedEvent>(x => x.OrderId, x => x.OrderId);
}
// start cancellation process
public void Handle(CancelOrderCommand message)
{
// check if cancellation is authorized and valid
// ....
// can save prior state here, if needed
this.Data.OrderId = message.OrderId;
this.Data.State = "Cancelling";
this.Bus.Send(new RefundOrderCommand(...));
}
public void Handle(RefundCompletedEvent message)
{
this.Data.State = "Cancelled";
this.OrderService.CompleteCancellation(...);
MarkAsComplete();
}
// this handler can be hosted on a different endpoint.
public void Handle(RefundOrderCommand message)
{
try
{
this.PaymentGateway.Refund(...
}
catch(Exception ex)
{
this.Bus.Reply(new PaymentGatewayInteractionFailedEventmessage(...));
}
}
// this handler can be used to revert whole operation.
public void Handle(PaymentGatewayInteractionFailedEvent message)
{
// or revert to prior state.
this.Data.Status = "Cancellation Failed";
// call any application services needed.
// finishes saga, deleting state
MarkAsComplete();
}
}