如何设计一个由接收多个消息启动的NServiceBus Saga

本文关键字:消息 启动 Saga NServiceBus 一个 | 更新日期: 2023-09-27 18:07:02

我正试图找到在NServiceBus 5中设计Saga的帮助。由2个或更多消息开始的X。这意味着传奇不会以单个消息开始,但所有消息必须在传奇开始之前出现。

我不太明白这是如何工作的,而且在任何地方都找不到样本或例子。

我读过几本书,书中明确指出,用几条信息来开始一个传奇是完全可以的。

我不明白的是,当你需要3条消息来启动传奇时,如何找到传奇。在故事"开始"之前,这三条信息必须以任何顺序到达。这如何影响我对[Unique]属性的选择?

示例:我需要一个"唯一"的saga,它由三个id"StoreID","ComputerID","UserID"标识。这三个id将以三个不同的命令到达,Message1, Message2, Message3

public class MySaga : Saga<MySagaData>, 
IAmStartedByMessages<Message1>, 
IAmStartedByMessages<Message2>, 
IAmStartedByMessages<Message3>
{ ...
}

MySagaData应该在三个属性上有[Unique]属性吗?

public class MySagaData
{
    [Unique]
    public int StoreId {get;set;}
    [Unique]
    public int ComputerId {get;set;}
    [Unique]
    public int UserId {get;set;}
}

或者我必须创建一个readonly属性连接这三个吗?

Message1Message3到达时,saga无法启动。Message2缺失

另一个Message1到达。

然后Message2到达。(完成第一个传奇,这样就可以开始了)

第二个Message1呢?

如何处理?

如何设计一个由接收多个消息启动的NServiceBus Saga

您的Saga实现接收到的每个消息将只属于该Saga的一个实例。您仍然需要在这3条消息中使用某种方法将它们与相同的Saga实例关联起来。

我会重新审视你的流程,看看是什么将这3个实体的任意三种组合绑定在一起,以找到唯一标识Saga的东西,例如Order。

在此之后,您的Saga可以等待,直到它接收到所有3条消息,开始做您想做的任何事情,通过检查所有这三个id都已设置,然后再做Saga需要做的任何事情。

saga不支持您所描述的模式。IAmStartedByMessages指令使用ANY语义,而不是ALL。

一般来说,你有两个选择;

  1. 用一条所需的消息启动您的saga实例,然后在其他消息发送时处理它们的到达,或者
  2. 在调用您的saga之前的某个时刻实现Aggregator或Observer模式,这显然将消除等待多个消息的需求。

在我看来,开始一段传奇的行为就是一段传奇。如果您创建了一个传奇来管理消息集合,然后启动一个不同的传奇来执行等待这些消息到达的任何工作,那会怎么样呢?