MassTransit帮助注册多个saga



我正在将一个旧应用程序移植到.net6,遇到了用masstrait注册多个saga的问题。

services.AddMassTransit<IProcessManagerBus>(busCfg =>
{
busCfg.AddSagaStateMachine<OrderPM, OrderPMState>()
.EntityFrameworkRepository<OrderPMState>(efConfig =>
{
efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
efConfig.DatabaseFactory(() => new OrderStateDbContext(configuration.GetConnectionString("DB")));
});

busCfg.AddSagaStateMachine<CsaLoginPM, CsaLoginPMState>()
.EntityFrameworkRepository<CsaLoginPMState>(efConfig =>
{
efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
efConfig.DatabaseFactory(() => new CsaLoginStateDbContext(configuration.GetConnectionString("DB")));
});

busCfg.UsingRabbitMq((context, rabbitCfg) =>
{
rabbitCfg.UseJsonSerializer();
rabbitCfg.Host(new Uri(configuration.GetValue<string>("messaging:pm-bus:host-address")), hostCfg =>
{
hostCfg.Username(configuration.GetValue<string>("messaging:pm-bus:username"));
hostCfg.Password(configuration.GetValue<string>("messaging:pm-bus:password"));        

rabbitCfg.ReceiveEndpoint(configuration.GetValue<string>("messaging:pm-bus:receive-queue"), epCfg =>
{
epCfg.PrefetchCount = 10;
epCfg.UseRetry(retryConfig => retryConfig.Exponential(5, TimeSpan.FromMilliseconds(500), TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(1)));

epCfg.ConfigureSagas(context);
});
});
});
});

OrderPMState工作正常,但CsaLoginPMState在触发时会出现以下错误:System.InvalidOperationException:实体类型CsaLoginPMState不是当前上下文的模型的一部分

如果我注释掉OrderPMState的注册,CsaLoginPMState就可以正常工作。我怀疑,这两个saga正在使用相同的DbContext,尽管它们是用各自的DbContext注册的。

OrderStateDbContext

public class OrderStateDbContext : SagaDbContext
{
public OrderStateDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
protected override IEnumerable<ISagaClassMap> Configurations
{
get { yield return new OrderPMStateMapping(); }
}
}

CsaLoginSteDbContext

public class CsaLoginStateDbContext : SagaDbContext
{
public CsaLoginStateDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
protected override IEnumerable<ISagaClassMap> Configurations
{
get { yield return new CsaLoginPMStateMapping(); }
}
}

旧版本的应用程序使用AutoFac,注册是这样完成的:

builder.Register(x =>
EntityFrameworkSagaRepository<OrderPMState>.CreateOptimistic(() => new OrderStateDbContext(_configuration.GetConnectionString("DB"))))
.As<ISagaRepository<OrderPMState>>().SingleInstance();
builder.Register(x =>
EntityFrameworkSagaRepository<CsaLoginPMState>.CreateOptimistic(() => new CsaLoginStateDbContext(_configuration.GetConnectionString("DB"))))
.As<ISagaRepository<CsaLoginPMState>>().SingleInstance();

我是不是错过了什么?

使用DbContext时,应使用专门为DbContext设计的两种配置方法之一。

busCfg.AddSagaStateMachine<CsaLoginPM, CsaLoginPMState>()
.EntityFrameworkRepository<CsaLoginPMState>(efConfig =>
{
efConfig.ConcurrencyMode = ConcurrencyMode.Optimistic;
efConfig.AddDbContext<DbContext, CsaLoginStateDbContext>((provider,builder) =>
{
builder.UseSqlServer(configuration.GetConnectionString("DB"), m =>
{
m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name);
m.MigrationsHistoryTable($"__{nameof(CsaLoginStateDbContext)}");
});
});
});

或者你可以单独添加DbContext,并在传奇中使用现有的DbContext:


services.AddDbContext<CsaLoginStateDbContext>(builder =>
builder.UseSqlServer(configuration.GetConnectionString("DB"), m =>
{
m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name);
m.MigrationsHistoryTable($"__{nameof(CsaLoginStateDbContext)}");
}));
services.AddMassTransit(x =>
{
x.AddSagaRepository<JobSaga>()
.EntityFrameworkRepository(r =>
{
r.ConcurrencyMode = ConcurrencyMode.Optimistic;
r.ExistingDbContext<CsaLoginStateDbContext>();
});
});

这些都包含在文档中。

最新更新