我想在Masstransit Sagas中使用独特的自然键而不是在Guid CorrelationId中构建。然而它似乎并没有真正起作用。 如果我发送两次具有相同键值的Initial事件,则在存储库中创建两个Sagas - 预期是单个实例。 使用CorrelationId的相同方案在存储库中生成一个Saga实例。
任何想法,为什么第二个Saga实例使用相同的密钥创建,忽略相关性声明?
以下是单元测试的简短示例:
[TestFixture]
public class SagaTests
{
[Test]
public void TestSagaInitialization()
{
var testSaga = new TestSaga();
var testSagaRepository = new InMemorySagaRepository<TestSagaState>();
var busControl = Bus.Factory.CreateUsingInMemory(
cfg =>
{
cfg.ReceiveEndpoint("test_queue",
e =>
{
e.StateMachineSaga(testSaga, testSagaRepository);
});
});
busControl.Start();
busControl.Publish(new TestSagaInitEvent() { UniqueNaturalKey = 1 }).Wait();
busControl.Publish(new TestSagaInitEvent() { UniqueNaturalKey = 2 }).Wait();
// Message with same natural key published again
busControl.Publish(new TestSagaInitEvent() { UniqueNaturalKey = 1 }).Wait();
// Wait till all messges consumed
var till = DateTime.Now.AddSeconds(1);
while (DateTime.Now < till) { System.Threading.Thread.Sleep(50); }
busControl.Stop();
var sagaInstances = testSagaRepository.Where(x => x.UniqueNaturalKey == 1).Result.ToList();
Assert.AreEqual(1, sagaInstances.Count, "Dublicate initial events with same Natural Key value must not create new Saga instance");
}
}
public class TestSagaState : Automatonymous.SagaStateMachineInstance
{
public Guid CorrelationId { get; set; }
public int CurrentState { get; set; }
public long UniqueNaturalKey { get; set; }
}
public class TestSaga : MassTransitStateMachine<TestSagaState>
{
public TestSaga()
{
InstanceState(x => x.CurrentState);
Event(() => SagaInitiated, x => x.CorrelateById(state => state.UniqueNaturalKey, context => context.Message.UniqueNaturalKey)
.SelectId(context => Guid.NewGuid()));
Initially(
When(SagaInitiated)
.Then(context =>
{
context.Instance.UniqueNaturalKey = context.Data.UniqueNaturalKey;
})
.TransitionTo(Initiated)
);
}
public State Initiated { get; private set; }
public Event<TestSagaInitEvent> SagaInitiated { get; private set; }
}
public class TestSagaInitEvent
{
public long UniqueNaturalKey { get; set; }
}