会议管理限界上下文在其Azure SQL数据库实例中的PricedOrders表中存储来自订单和注册限界上下文的订单信息。以前,会议管理限界上下文接收OrderPaymentConfirmed事件,现在它接收OrderConfirmed事件,该事件包含一个附加的IsFreeOfCharge属性。这将成为数据库中的一个新列。
Markus(软件开发人员)发言:在迁移过程中,我们不需要修改该表中的现有数据,因为布尔值的默认值为false。所有现有条目都是在系统支持不需要付费的订单之前创建的。
在迁移过程中,任何正在运行的ConfirmOrderPayment命令都可能丢失,因为它们不再由订单聚合处理。您应该验证当前的命令总线没有这些命令。
Poe(IT运维人员)发言:我们需要仔细计划如何部署V2版本,以便确保所有现有的、正在运行的ConfirmOrderPayment命令都由运行V1版本的工作角色实例处理。
系统将RegistrationProcessManager类实例的状态保存到SQL数据库表中。这个表的架构没有变化。迁移后您将看到的惟一更改是StateValue列中的一个新添加值。这反映了RegistrationProcessManager类中的ProcessState枚举中额外的PaymentConfirmationReceived值,如下面的代码示例所示:
public enum ProcessState { NotStarted = 0, AwaitingReservationConfirmation = 1, ReservationConfirmationReceived = 2, PaymentConfirmationReceived = 3, }在V1版本中,事件源系统为订单聚合保存的事件包括OrderPaymentConfirmed事件。因此,事件存储区包含此事件类型的实例。在V2版本中,OrderPaymentConfirmed事件被替换为OrderConfirmed事件。
团队决定在V2版本中,当反序列化事件时,不在基础设施级别映射和过滤事件。这意味着,当系统从事件存储中重播这些事件时,处理程序必须同时理解旧事件和新事件。下面的代码示例在SeatAssignmentsHandler类中显示了这一点:
static SeatAssignmentsHandler() { Mapper.CreateMap<OrderPaymentConfirmed, OrderConfirmed>(); } public SeatAssignmentsHandler(IEventSourcedRepository<Order> ordersRepo, IEventSourcedRepository<SeatAssignments> assignmentsRepo) { this.ordersRepo = ordersRepo; this.assignmentsRepo = assignmentsRepo; } public void Handle(OrderPaymentConfirmed @event) { this.Handle(Mapper.Map<OrderConfirmed>(@event)); } public void Handle(OrderConfirmed @event) { var order = this.ordersRepo.Get(@event.SourceId); var assignments = order.CreateSeatAssignments(); assignmentsRepo.Save(assignments); }您还可以在OrderViewModelGenerator类中看到同样的技术。
Order类中的方法略有不同,因为这是持久化到事件存储中的事件之一。下面的代码示例显示了Order类中受保护构造函数的一部分:
protected Order(Guid id) : base(id) { ... base.Handles<OrderPaymentConfirmed>(e => this.OnOrderConfirmed(Mapper.Map<OrderConfirmed>(e))); base.Handles<OrderConfirmed>(this.OnOrderConfirmed); ... } Jana(软件架构师)发言:以这种方式处理旧事件对于这个场景非常简单,因为惟一需要更改的是事件的名称。如果事件的属性也发生了变化,情况会更加复杂。将来,Contoso将考虑在基础设施中进行映射,以避免遗留事件污染领域模型。 在UI中显示剩余座位
做出这一改变有三个具体的目标,它们都是相关的。我们想要:
修改系统,在会议系统的读模型中包含每个座位类型的剩余座位数量信息。
修改UI以显示每种座位类型的剩余座位数量。
确保升级到V2后系统功能正常。
向读模型添加关于剩余座位数量的信息系统要能显示剩余座位数量的信息来自两个地方:
当业务客户创建新的座位类型或修改座位配额时,会议管理限界上下文将引发SeatCreated和SeatUpdated事件。
在订单和注册限界上下文中,当注册者创建一个订单的时候,可用座位(SeatsAvailability)聚合将引发SeatsReserved、SeatsReservationCancelled和AvailableSeatsChanged事件。
备注:ConferenceViewModelGenerator类不使用SeatCreated和SeatUpdated事件。