如何通过CompositeEvent传递事件属性?状态机数据传递疑问
我在状态机中定义了以下事件:
public Event<FirstCompletedEvent>? FirstCompletedEvent { get; set; } public record FirstCompletedEvent(Guid PaymentKey, string PaymentDetails) : IQueueMessage; public Event<SecondCompletedEvent>? SecondCompletedEvent { get; set; } public Event<ThirdCompletedEvent>? ThirdCompletedEvent { get; set; }
通过以下配置,当上述三个事件全部到达时触发AllCompletedEvent:
CompositeEvent(() => AllCompletedEvent, x => x.AllCompletedEventStatus, FirstCompletedEvent, SecondCompletedEvent, ThirdCompletedEvent);
需求:希望将FirstCompletedEvent中的PaymentDetails数据传递到AllCompletedEvent的处理逻辑中,实现类似如下的代码:
During(Payout, When(AllCompletedEvent) .Then(c => DoSomething(c.Data.PaymentDetails))
我曾尝试在FirstCompletedEvent的事件处理器中将数据保存到状态,但该处理器(即便触发)也是在AllCompletedEvent触发后才执行,完全不符合需求:
When(FirstCompletedEvent) .Then(c => c.Instance.PaymentDetails = c.Data.PaymentDetails)
解决方案
1. 确保单个事件处理器优先执行
首先检查FirstCompletedEvent的处理器配置,确保它在事件到达时立即执行,而非等待复合事件触发。如果处理器和AllCompletedEvent同属Payout状态,需按如下方式配置:
During(Payout, When(FirstCompletedEvent) .Then(c => c.Instance.PaymentDetails = c.Data.PaymentDetails), When(AllCompletedEvent) .Then(c => DoSomething(c.Instance.PaymentDetails)) );
以常用的状态机框架(如MassTransit Saga)为例,事件到达时会先执行对应事件的处理器,再检查复合事件的触发条件。若处理器仍延迟执行,需排查复合事件的配置参数(如是否设置了强制等待所有事件的选项)或状态实例的事件状态标记是否正确。
2. 自定义复合事件数据
如果不想依赖状态存储,可通过CompositeEvent的dataFactory参数直接构建包含目标数据的复合事件对象:
首先更新AllCompletedEvent的定义,添加PaymentDetails字段:
public record AllCompletedEvent(string PaymentDetails); public Event<AllCompletedEvent>? AllCompletedEvent { get; set; }
然后修改复合事件配置,用dataFactory从状态中提取已保存的PaymentDetails:
CompositeEvent(() => AllCompletedEvent, x => x.AllCompletedEventStatus, dataFactory: context => new AllCompletedEvent(context.Instance.PaymentDetails), FirstCompletedEvent, SecondCompletedEvent, ThirdCompletedEvent);
这样在处理AllCompletedEvent时,就能直接通过c.Data.PaymentDetails获取所需数据。
3. 调整事件处理优先级
若以上方法无效,可检查状态机框架的事件处理优先级配置,确保单个事件的处理器逻辑先于复合事件的触发逻辑执行。
内容的提问来源于stack exchange,提问作者Proggear

