简体   繁体   中英

How to configure MassTransit Saga in Asp.Net Core application

I'm trying to integrate simple MassTransit Saga into ASP.NET Core application. During ConfigureServices I have:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ISagaRepository<Request>, InMemorySagaRepository<Request>>();
    services.AddMassTransit(x =>
    {
        x.AddSagaStateMachine<RequestStateMachine, Request>();
        x.AddBus(provider => Bus.Factory.CreateUsingInMemory(cfg =>
        {
            cfg.UseInMemoryOutbox();
            cfg.ConfigureEndpoints(provider);
        }));
    });
}

Later I publish message:

var bus = context.RequestServices.GetService<IBusControl>();
await bus.Publish<IRequestCreated>(new
{
    CorrelationId = Guid.NewGuid(),
    ClientId = 1,
});

but it never reaches Saga instance.

My Saga looks like this:

    public class RequestStateMachine : MassTransitStateMachine<Request>
    {
        public RequestStateMachine()
        {
            InstanceState(x => x.CurrentState);

            Event(
                () => RequestCreated,
                x => x.CorrelateById(context => context.Message.CorrelationId).SelectId(context => Guid.NewGuid()));

            Initially(
                When(RequestCreated)
                    .Then(context =>
                    {
                        Console.WriteLine($"Request received, id = {context.Instance.CorrelationId}");
                        context.Instance.RequestId = 10;
                    })
                    .TransitionTo(Active)
            );

            SetCompletedWhenFinalized();
        }

        public State Active { get; protected set; }

        public Event<IRequestCreated> RequestCreated { get; protected set; }
    }

    public class Request : SagaStateMachineInstance
    {
        public string CurrentState { get; set; }

        public Guid CorrelationId { get; set; }

        public long RequestId { get; set; }

        public Guid? ExpirationId { get; set; }
    }

I guess I'm doing something wrong but can't figure out what.

I have to admit it is a bit confusing. We have AddMassTransit methods both in Microsoft DI package and ASP.NET Core integration package and they do different things.

AddMassTransit from the AspNetCoreIntegration package also registers the service that starts and stops the bus. So, this code would solve your issue:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ISagaRepository<Request>, InMemorySagaRepository<Request>>();
    services.AddMassTransit(
        provider => 
            Bus.Factory.CreateUsingInMemory(cfg =>
            {
                cfg.UseInMemoryOutbox();
                cfg.ConfigureEndpoints(provider);
            },
        x => x.AddSagaStateMachine<RequestStateMachine, Request>()
    );
}

The method you use just registers the bus as IBus , IBusControl , ISendEndpointProvider and IPublishEndpointPervider in the container, but it doesn't take care about starting and stopping the bus. The method I used in the code sample also registers the host service and (optionally) adds health checks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM