假设我们有以下业务规则:
如果我们同步这样做,我对交易范围有疑问:
Bus.InMemory
执行此操作? The documentation在这件事上并不十分清楚。代码如下:
public class CancelOrder : ICommand
{
public Guid Id { get; set; }
}
public class OrderCancelled : IEvent
{
public Guid Id { get; set; }
}
public class CancelShipment : ICommand
{
public Guid Id { get; set; }
}
public class CancelOrderHandler : IHandleMessages<CancelOrder>
{
private DbContext _dbContext;
private IBus _bus;
public void Handle(CancelOrder message)
{
var order = _dbContext.Orders.Single(x => x.Id == message.Id);
// do some validation here
order.Status = OrderStatus.Cancelled;
// unsure about whether to call _dbContext.SaveChanges() or not
_bus.Publish(new OrderCancelled {
Id = message.Id
});
}
}
public class OrderCancelledHandler : IHandleMessages<OrderCancelled>
{
private DbContext _dbContext;
private IBus _bus;
public void Handle(CancelOrder message)
{
var commands = _dbContext.Shipments
.Where(x => x.OrderId == message.Id && x.Status != ShipmentStatus.Shipped)
.Select(x => new CancelShipment {
Id = x.Id
});
_bus.Send(commands);
}
}
public CancelShipmentHandler : IHandleMessages<CancelShipment>
{
private DbContext _dbContext;
public void Handle(CancelShipmentHandler message)
{
// Similar to CancelOrder, only with shipments.
}
}
答案 0 :(得分:3)
这里的答案取决于业务要求 - 例如,如果我们无法取消其中一个货件,这是否意味着我们应该取消订单的取消?
我的感觉是答案可能不是。因此,您使用的消息驱动模型似乎比在单个处理程序中同步执行所有操作更合适。
我对您的代码的一个小问题是您在OrderCancelledHandler中发布命令。你可能应该Bus.Send他们。
此外,通过执行单个Bus.Publish / Bus.Send,您指示完整命令集的处理应该是一个事务。我不认为你想要那个。相反,我建议循环执行命令并分别为每个命令执行Bus.Send。