几天来我一直在与这个问题作斗争,但是找不到真正可行的方法。
我的情况是我有一个状态机传奇,我想在其中运行与传奇运行相同的事务(实体框架)中的东西,以便状态和业务事物并存。
现在,我已经了解到状态机本身不应该具有任何依赖性,因此可以添加此Activity(x => x.OfInstanceType<MyActivity>)
活动,该活动可以从DI容器中解析出来,并且可以具有任何依赖性(服务等)在里面。到目前为止一切顺利...
我的问题是,无论我在活动中执行什么,都无法使其正常工作。它是从容器中解析出来的,并且调用了Execute
方法,但是随后退出了。
看来这里抛出了一些异常,但是显然并没有冒充测试工具。
我正在使用Microsoft的dotnet核心依赖注入库。
这是一些代码
public class MyStateMachine : MassTransitStateMachine<SagaInstance>
{
public MyStateMachine()
{
InstanceState(instance => instance.CurrentState);
Event(() => Start, x => x.CorrelateBy(saga => saga.CorrelationId, context => context.Message.CorrelationId));
Initially(
When(Start)
.Activity(c => c.OfType<MyActivity>())
.TransitionTo(Running)
.Publish(new Started())
);
}
Event<Run> Start { get; set;}
State Running { get; set; }
}
public class MyActivity : Activity<SagaInstance, Run>
{
private readonly IMyService _service;
public MyActivity(IMyService service)
{
_service = service;
}
public async Task Execute(BehaviorContext<SagaInstance, Run> context, Behavior<SagaInstance, Run> next)
{
//throw new Exception("BOO"); // uncommenting this line doesn't throw anywhere
_service.DoThatThing();
await next.Execute(context).ConfigureAwait(false);
}
}
[Fact]
public async Task RunMessageSent_NonexistingSaga_StateIsRunning()
{
var harness = new InMemoryTestHarness();
var machine = new MyStateMachine();
var collection = new ServiceCollection();
collection.AddMassTransit();
collection.RegisterInMemorySagaRepository<SagaInstance>();
collection.RegisterSagaStateMachine<MyStateMachine, SagaInstance>();
collection.AddScoped<MyActivity>();
collection.AddScoped<MyService>();
var provider = collection.BuildServiceProvider();
harness.OnConfigureInMemoryReceiveEndpoint += cfg => cfg.StateMachineSaga(machine, provider);
await harness.Start();
try
{
var guid = CorrelationId = Guid.NewGuid();
await harness.InputQueueSendEndpoint.Send(new Run({CorrelationId = guid}));
var repo = provider.GetService<ISagaRepository<SagaInstance>>() as InMemorySagaRepository<SagaInstance>;
var saga = await repo.ShouldContainSaga(s => s.Serial == serial, timeout: TimeSpan.FromSeconds(1));
Assert.NotNull(saga);
// this Equal fails saying the saga is in state Initial
Assert.Equal(machine.Running.Name, repo[saga.Value].Instance.CurrentState);
}
finally
{
await harness.Stop();
}
}
答案 0 :(得分:0)
我在dotnet core 2.1上运行,经过大量搜索和浏览Masstransit存储库后,我意识到最新的(5.3)Masstransit中有更好的Dependency Injection框架API,我不想升级。首先避免必须同时将dotnet运行时依赖项升级到2.2。
完成升级后,我开始意识到必须存在一些异步问题,因为有时我会随机工作。然后我意识到内存中有另一种方法称为ShouldContainSagaInState
。
因此,通过使用此行,我可以正常工作!
var saga = await repo.ShouldContainSagaInState(guid, machine, x => x.Running, TimeSpan.FromSeconds(1));
还使用请求/响应模式按照我打算的方式运行代码,潜在的异常作为故障消息发送回调用方。在测试工具中,此消息以某种方式可用,但是我尚未研究检查它的正确方法。
答案 1 :(得分:0)
我已经创建了一个简单的活动,并在IOC中注册了它,就像您所做的那样,但是有一个例外:
GreenPipes.PayloadNotFoundException: The payload was not found: Automatonymous.IStateMachineActivityFactory
at GreenPipes.PipeExtensions.GetPayload[TPayload](PipeContext context)
at Automatonymous.Activities.ContainerFactoryActivity`3.Automatonymous.Activity<TInstance,TData>.Execute(BehaviorContext`2 context, Behavior`2 next)
at Automatonymous.Activities.DataConverterActivity`2.Automatonymous.Activity<TInstance>.Execute[T](BehaviorContext`2 context, Behavior`2 next)
at Automatonymous.Behaviors.LastBehavior`1.Automatonymous.Behavior<TInstance>.Execute[T](BehaviorContext`2 context)
at Automatonymous.States.StateMachineState`1.Automatonymous.State<TInstance>.Raise[T](EventContext`2 context)
at Automatonymous.States.StateMachineState`1.Automatonymous.State<TInstance>.Raise[T](EventContext`2 context)
at Automatonymous.AutomatonymousStateMachine`1.Automatonymous.StateMachine<TInstance>.RaiseEvent[T](EventContext`2 context)
at Automatonymous.Pipeline.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next)
at MassTransit.EntityFrameworkCoreIntegration.Saga.EntityFrameworkSagaRepository`1.MassTransit.Saga.ISagaRepository<TSaga>.Send[T](ConsumeContext`1 context, ISagaPolicy`2 policy, IPipe`1 next)
我使用Masstransit 5.1.5 有什么问题吗?