如果我们设置了一个Saga并立即Publish(context => ...)
,则一条消息成功到达总线。
然而,如果我们有类似的东西
Initially(
When(SomeCommand)
.Then(context => { context.Instance.SomeField = 5 })
.TransitionTo(SomeState)
.Then(context => this.RaiseEvent(context.Instance, SomeEvent)));
During(SomeState,
When(SomeEvent)
// ConsumeContext is not available here
.Publish(context => new SomeEventClass
{
Foo = context.Instance.SomeField
})
.Finalize());
机器也从未转换到最终状态,可能是因为定位ConsumerContext的异常。
我们已经看到一些关于在Publish()
中传递ConsumeContext
作为参数的引用,但尚不清楚这需要哪个上下文(Intellisense只引用了context1、context2、context3等(。
在已经调用了RaiseEvent()
之后,是否有方法使用Publish()
?如果没有,是否有办法使用其他机制发布事件?
MassTransit版本为5.1.5,Automatonymous版本为4.1.2
编辑根据Chris Patterson的回答,我们尝试在任何Initially
或During
之外添加以下内容
WhenEnter(NewState, state => state.Publish(context =>
new EventClass { Foo = context.Instance.Foo }
)
.Finalize();
然而,它仍然没有发布任何内容,并且状态从未转换到Final
。如果我们添加一个Then
,它也永远不会碰到这个代码块。似乎没有任何例外。我们还尝试过使用When(SomeState.Enter)
,但它也不起作用。
附带问题,也许这将有助于我理解为什么Publish
和RaiseEvent
在一起似乎不太好——为什么Publish
需要ConsumeContext
?它是用来定位总线和绑定的吗?
这个问题的解决方案原来是使用这个:
.Then(context => context.Raise(SomeEvent))
而不是这个:
.Then(context => this.RaiseEvent(context.Instance, SomeEvent))
现在有点道理了——后者(正如Chris Patterson所提到的(创建了一个新的EventContext
,而前者使用给定的context
。我们不知道Raise
是在传入的context
上可用的方法。
您应该能够添加
When(SomeState.Enter)
到您的Initially
部分,它将使用现有的上下文。通过使用RaiseEvent
创建新的EventContext
,就不会保留ConsumeContext
。
您也可以在任何Initially
或During
块之外添加WhenEnter(SomeState)
。