0

我正在为分布式系统实现 Saga。到目前为止,我在使用 Masstransit 文档来实现没有任何有意义行为的 Saga 时没有遇到任何问题(只是一个带有几个微服务交换消息的协调器)。

下一步是在 Automatonymous 状态机的状态更改之间添加一些行为。我有一个具有所有必需行为的服务,所以我想创建使用依赖注入的服务的海关活动。

问题是活动没有很好地解决,并引发以下错误:

Automatonymous.EventExecutionException: The ArchivosEnviados<ArchivosEnviadosAAlfresco> (Event) execution faulted
 ---> System.MissingMethodException: No parameterless constructor defined for type 'Confuturo.Microservicios.BackendAppSucursalVirtual.Sagas.Activities.EnviarCorreoActivity'.
   at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type)
   at Automatonymous.DefaultConstructorStateMachineActivityFactory.GetActivity[TActivity,TInstance](BehaviorContext`1 context)
   at Automatonymous.Activities.ContainerFactoryActivity`2.Automatonymous.Activity<TInstance>.Execute(BehaviorContext`1 context, Behavior`1 next)
   at Automatonymous.Activities.SlimActivity`2.Automatonymous.Activity<TInstance,TData>.Execute(BehaviorContext`2 context, Behavior`2 behavior)
   at Automatonymous.Activities.DataConverterActivity`2.Automatonymous.Activity<TInstance>.Execute[T](BehaviorContext`2 context, Behavior`2 next)
   at Automatonymous.Behaviors.ActivityBehavior`1.Automatonymous.Behavior<TInstance>.Execute[T](BehaviorContext`2 context)
   --- End of inner exception stack trace ---
   at Automatonymous.Behaviors.ExceptionBehavior`2.Automatonymous.Behavior<TInstance,TData>.Faulted[TException](BehaviorExceptionContext`3 context)
   at Automatonymous.Activities.SlimActivity`2.Automatonymous.Activity<TInstance,TData>.Faulted[TException](BehaviorExceptionContext`3 context, Behavior`2 next)
   at Automatonymous.Activities.DataConverterActivity`2.Automatonymous.Activity<TInstance>.Faulted[T,TException](BehaviorExceptionContext`3 context, Behavior`2 next)
   at Automatonymous.Behaviors.LastBehavior`1.Automatonymous.Behavior<TInstance>.Faulted[T,TException](BehaviorExceptionContext`3 context)
   at Automatonymous.Behaviors.DataBehavior`2.Automatonymous.Behavior<TInstance,TData>.Faulted[TException](BehaviorExceptionContext`3 context)
   at Automatonymous.Behaviors.ExceptionTypeCache.CachedConfigurator`1.Automatonymous.Behaviors.ExceptionTypeCache.CachedConfigurator.Faulted[TInstance,TData](Behavior`2 behavior, BehaviorContext`2 context, Exception exception)
   at Automatonymous.Behaviors.ExceptionTypeCache.Faulted[TInstance,TData](Behavior`2 behavior, BehaviorContext`2 context, Exception exception)
   at Automatonymous.Behaviors.ActivityBehavior`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 Automatonymous.Pipeline.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next)
   at MassTransit.Saga.SendSagaPipe`2.Send(SagaRepositoryContext`2 context)
   at MassTransit.Saga.SendSagaPipe`2.Send(SagaRepositoryContext`2 context)
   at MassTransit.Saga.InMemoryRepository.InMemorySagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, IPipe`1 next)
   at MassTransit.Saga.Pipeline.Filters.CorrelatedSagaFilter`2.GreenPipes.IFilter<MassTransit.ConsumeContext<TMessage>>.Send(ConsumeContext`1 context, IPipe`1 next) 

文档没有明确说明我们应该如何使用 .NET Core 的默认 DI 系统包含自定义活动。我还在 Stackoverflow、Github 存储库和Google Group中查找了这些信息。

在我的 Startup 课程中,我按照官方文档中的说明配置了 Masstransit:

services.AddMassTransit(c =>
            {
                var machineGenerica = new SolicitudGenericStateMachine();
                var repositoryGenerico = new InMemorySagaRepository<SolicitudGenericInstance>();                      

                c.AddConsumer<MensajeDocumentoFirmadoConsumer>();
                c.AddBus(context => Bus.Factory.CreateUsingActiveMq(cfg =>
                {
                    cfg.ReceiveEndpoint("solicitud-generica-saga", e =>
                    {
                        e.StateMachineSaga(machineGenerica, repositoryGenerico);
                    });                       
                    cfg.UseHealthCheck(context);
                    cfg.Host(activeMqOptions.Host, activeMqOptions.Port, hostConfigure =>
                    {
                        hostConfigure.Username(activeMqOptions.Username);
                        hostConfigure.Password(activeMqOptions.Password);
                    });

                    cfg.ReceiveEndpoint(activeMqOptions.EndpointDocumentoFirmado, ep =>
                    {
                        ep.PrefetchCount = 1;
                        ep.Consumer<MensajeDocumentoFirmadoConsumer>(context);
                    });
                }));                
            });
services.AddMassTransitHostedService();               
services.AddScoped<EnviarCorreoActivity>();

如果我理解正确,我必须以某种方式使用IStateMachineActivityFactory但我真的迷失了如何继续。任何帮助将不胜感激。

4

1 回答 1

2

您应该使用以下方法在容器中注册您的状态机:

c.AddSagaStateMachine< SolicitudGenericStateMachine, SolicitudGenericInstance >()
    .InMemoryRepository();

然后,使用以下命令配置 saga:

cfg.ReceiveEndpoint("solicitud-generica-saga", e =>
{
    e.ConfigureSaga<SolicitudGenericInstance>(context);
});  

您注册为范围的活动是正确的。

于 2020-07-01T10:47:26.723 回答