如果不更改 saga 以及客户端系统正在发送的消息,您将无法解决此问题。
您的问题是 saga 可能配置为在收到某种消息类型时启动,每次用户对客户进行更改时,客户端应用程序都会生成该消息类型。
让我们将此消息称为:
public class ClientTypedSomethingAboutCustomer
{
int CustomerId {get;set;}
...
}
您的传奇将设置如下:
public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
{
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<ClientTypedSomethingAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
...
}
...
}
这会导致初始化 saga 并在 IContainSagaData 实现中设置客户 ID 值,用于接收到的每条客户端消息。
要解决更多消息初始化新 saga 的问题,您可以创建另一种消息类型,以区分某人何时开始键入有关客户的内容,然后键入有关该客户的其他内容。
就像是:
public class ClientTypedSomethingElseAboutCustomer
{
int CustomerId {get;set;}
...
}
那么你的传奇会是这样的:
public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
,IHandleMessages<ClientTypedSomethingElseAboutCustomer>
{
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<ClientTypedSomethingAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
ConfigureMapping<ClientTypedSomethingElseAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
}
...
}
这将确保有关客户的所有消息都将路由到单个 saga 实例。
通过在单线程模式下运行 NServiceBus 可以实现近似的排队行为。这可能会限制为客户创建并发 saga,但我不想依赖这个。