public When_using_EntityFrameworkConcurrencyFail() { _sagaDbContextFactory = new DelegateSagaDbContextFactory <ChoirStateOptimistic>( () => new SagaDbContext <ChoirStateOptimistic, EntityFrameworkChoirStateMap>(SagaDbContextFactoryProvider.GetLocalDbConnectionString())); _repository = new Lazy <ISagaRepository <ChoirStateOptimistic> >(() => EntityFrameworkSagaRepository <ChoirStateOptimistic> .CreateOptimistic(_sagaDbContextFactory)); }
public When_using_EntityFramework() { _sagaDbContextFactory = new DelegateSagaDbContextFactory <ShoppingChore>( () => new ShoppingChoreSagaDbContext(SagaDbContextFactoryProvider.GetLocalDbConnectionString())); _repository = new Lazy <ISagaRepository <ShoppingChore> >(() => EntityFrameworkSagaRepository <ShoppingChore> .CreatePessimistic(_sagaDbContextFactory)); }
public When_pre_inserting_the_state_machine_instance_using_ef() { ISagaDbContextFactory <Instance> sagaDbContextFactory = new DelegateSagaDbContextFactory <Instance>( () => new InstanceSagaDbContext(LocalDbConnectionStringProvider.GetLocalDbConnectionString())); _repository = EntityFrameworkSagaRepository <Instance> .CreatePessimistic(sagaDbContextFactory); }
public When_using_EntityFrameworkConcurrencyPessimistic() { _sagaDbContextFactory = new DelegateSagaDbContextFactory <ChoirStatePessimistic>(() => new ChoirStatePessimisticSagaDbContext(LocalDbConnectionStringProvider.GetLocalDbConnectionString())); _repository = new Lazy <ISagaRepository <ChoirStatePessimistic> >(() => EntityFrameworkSagaRepository <ChoirStatePessimistic> .CreatePessimistic(_sagaDbContextFactory)); }
private static IBusControl ConfigureReadBus() { var expertTaggingStateMachine = new SampleSaga(); SagaDbContextFactory sagaDbContextFactory = () => new SagaDbContext <SampleSagaState, SampleSagaMapping>("default"); var stateMachineRepository = new EntityFrameworkSagaRepository <SampleSagaState>(sagaDbContextFactory); var busControl = Bus.Factory.CreateUsingAzureServiceBus(cfg => { cfg.UseNLog(); IServiceBusHost host = cfg.Host(ConfigurationManager.AppSettings["azureServiceBus:ConnectionString"], hcfg => { }); cfg.ReceiveEndpoint(host, "sample_queue", ecfg => { ecfg.StateMachineSaga(expertTaggingStateMachine, stateMachineRepository); }); }); var observer = new ReceiveObserver(true); busControl.ConnectReceiveObserver(observer); return(busControl); }
public Locating_an_existing_ef_saga() { var sagaDbContextFactory = new DelegateSagaDbContextFactory <SimpleSaga>(() => new SimpleSagaDbContext(LocalDbConnectionStringProvider.GetLocalDbConnectionString())); _sagaRepository = new Lazy <ISagaRepository <SimpleSaga> >(() => EntityFrameworkSagaRepository <SimpleSaga> .CreatePessimistic(sagaDbContextFactory)); }
private IBusControl ConfigureBus() { return(Bus.Factory.CreateUsingRabbitMq(cfg => { IRabbitMqHost host = cfg.Host(new Uri("rabbitmq://localhost"), h => { h.Username("guest"); h.Password("guest"); }); cfg.ReceiveEndpoint("issue_request_state", endpoint => { var optionsBuilder = new DbContextOptionsBuilder <IssueRequestDbContext>(); optionsBuilder.UseSqlServer(connectionString); var repository = new EntityFrameworkSagaRepository <IssueRequest>(() => new IssueRequestDbContext(optionsBuilder.Options)); //var repository = new InMemorySagaRepository<CustomerRequest>(); var machine = new IssueRequestSagaStateMachine(); endpoint.StateMachineSaga(machine, repository); }); })); }
public When_pre_inserting_in_an_invalid_state_with_ef() { SagaDbContextFactory sagaDbContextFactory = () => new SagaDbContext <Instance, EntityFrameworkInstanceMap>(SagaDbContextFactoryProvider.GetLocalDbConnectionString()); _repository = new EntityFrameworkSagaRepository <Instance>(sagaDbContextFactory); }
private static void ConfigureServiceBus(IServiceCollection services, IConfiguration configuration) { var rabbitMqSettings = configuration.GetSection(nameof(RabbitMq)).Get <RabbitMq>(); var rabbitBaseUri = $"amqp://{rabbitMqSettings.Host}:{rabbitMqSettings.Port}"; var factory = new Factory(); ISagaDbContextFactory <Investigation> contextFactory = new DelegateSagaDbContextFactory <Investigation>(() => factory.CreateDbContext(Array.Empty <string>())); var repository = new EntityFrameworkSagaRepository <Investigation>(contextFactory); // Register Mass Transit services.AddMassTransit(x => { // Add RabbitMq Service Bus x.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg => { var investigationStateMachine = new InvestigationStateMachine(configuration.GetSection("providers").Get <List <Provider> >()); var host = cfg.Host(new Uri(rabbitBaseUri), hostConfigurator => { hostConfigurator.Username(rabbitMqSettings.Username); hostConfigurator.Password(rabbitMqSettings.Password); }); cfg.ReceiveEndpoint(host, "investigation_state", e => { e.StateMachineSaga(investigationStateMachine, repository); }); })); }); }
public When_pre_inserting_in_an_invalid_state_using_ef() { var sagaDbContextFactory = new DelegateSagaDbContextFactory <Instance>(() => new InstanceSagaDbContext(SagaDbContextFactoryProvider.GetLocalDbConnectionString())); _repository = EntityFrameworkSagaRepository <Instance> .CreatePessimistic(sagaDbContextFactory); }
public Locating_an_existing_ef_saga() { // add new migration by calling // dotnet ef migrations add --context "SagaDbContext``2" Init -v _sagaRepository = new Lazy <ISagaRepository <SimpleSaga> >(() => EntityFrameworkSagaRepository <SimpleSaga> .CreatePessimistic( () => new SimpleSagaContextFactory().CreateDbContext(DbContextOptionsBuilder), RawSqlLockStatements)); }
public static void UseEntityFrameworkCoreSagaRepository(this IJobServiceConfigurator configurator, Func<JobServiceSagaDbContext> contextFactory, ILockStatementProvider lockStatementProvider = default) { configurator.Repository = EntityFrameworkSagaRepository<JobTypeSaga>.CreatePessimistic(contextFactory, lockStatementProvider); configurator.JobRepository = EntityFrameworkSagaRepository<JobSaga>.CreatePessimistic(contextFactory, lockStatementProvider); configurator.JobAttemptRepository = EntityFrameworkSagaRepository<JobAttemptSaga>.CreatePessimistic(contextFactory, lockStatementProvider); }
public Using_custom_include_in_repository() { // // add new migration by calling // // dotnet ef migrations add --context "SagaDbContext``2" Init -v _sagaRepository = new Lazy <ISagaRepository <SagaWithDependency> >(() => EntityFrameworkSagaRepository <SagaWithDependency> .CreatePessimistic( () => new SagaWithDependencyContextFactory().CreateDbContext(DbContextOptionsBuilder), RawSqlLockStatements, queryable => queryable.Include(it => it.Dependency).ThenInclude(dependency => dependency.SagaInnerDependency))); }
static async Task Main(string[] args) { var isService = !(Debugger.IsAttached || args.Contains("--console")); var builder = new HostBuilder() .ConfigureAppConfiguration((hostingContext, config) => { config.AddJsonFile("appsettings.json", optional: true); config.AddEnvironmentVariables(); if (args != null) { config.AddCommandLine(args); } }) .ConfigureServices((hostContext, services) => { services.Configure <AppConfig>(options => hostContext.Configuration.GetSection("AppConfig").Bind(options)); services.AddMassTransit(cfg => { cfg.AddConsumersFromNamespaceContaining <ConsumerAnchor>(); cfg.AddSagaStateMachinesFromNamespaceContaining <StateMachineAnchor>(); cfg.AddActivitiesFromNamespaceContaining <ActivitiesAnchor>(); cfg.AddBus(ConfigureBus); }); services.AddDbContext <DbContext, SampleBatchDbContext>(x => x.UseSqlServer(hostContext.Configuration.GetConnectionString("sample-batch"))); services.AddSingleton(typeof(ISagaDbContextFactory <BatchState>), typeof(SagaScopedDbConnectionFactory <BatchState>)); services.AddSingleton(typeof(ISagaDbContextFactory <JobState>), typeof(SagaScopedDbConnectionFactory <JobState>)); // I specified the MsSqlLockStatements because in my State Entities EFCore EntityConfigurations, I changed the column name from CorrelationId, to "BatchId" and "BatchJobId" // Otherwise I could just use the default, which are "... WHERE CorrelationId = @p0" services.AddSingleton <ISagaRepository <BatchState> >(x => EntityFrameworkSagaRepository <BatchState> .CreatePessimistic(x.GetRequiredService <ISagaDbContextFactory <BatchState> >(), new MsSqlLockStatements(rowLockStatement: "select * from {0}.{1} WITH (UPDLOCK, ROWLOCK) WHERE BatchId = @p0"))); services.AddSingleton <ISagaRepository <JobState> >(x => EntityFrameworkSagaRepository <JobState> .CreatePessimistic(x.GetRequiredService <ISagaDbContextFactory <JobState> >(), new MsSqlLockStatements(rowLockStatement: "select * from {0}.{1} WITH (UPDLOCK, ROWLOCK) WHERE BatchJobId = @p0"))); services.AddSingleton <IHostedService, MassTransitConsoleHostedService>(); services.AddSingleton <IHostedService, EfDbCreatedHostedService>(); // So we don't need to use ef migrations for this sample. Likely if you are going to deploy to a production environment, you want a better DB deploy strategy. }) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); }); if (isService) { await builder.RunAsServiceAsync(); } else { await builder.RunConsoleAsync(); } }
/// <summary> /// Create EntityFramework saga repository /// </summary> /// <param name="registrationConfigurator"></param> /// <param name="configure"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> public static IEntityFrameworkSagaRepository CreateEntityFrameworkSagaRepository(this IRegistrationConfigurator registrationConfigurator, Action <DbContextOptionsBuilder> configure) { if (configure == null) { throw new ArgumentNullException(nameof(configure)); } var optionsBuilder = EntityFrameworkSagaRepository.CreateOptionsBuilder(); configure(optionsBuilder); return(new EntityFrameworkSagaRepository(optionsBuilder.Options)); }
public SlowConcurrentSaga_Specs() { // rowlock statements that don't work to cause a deadlock. var notWorkingRowLockStatements = new SqlLockStatementProvider("dbo", "SELECT * FROM \"{1}\" WHERE \"CorrelationId\" = @p0"); // add new migration by calling // dotnet ef migrations add --context "SagaDbContext``2" Init -v _sagaRepository = new Lazy <ISagaRepository <SlowConcurrentSaga> >(() => EntityFrameworkSagaRepository <SlowConcurrentSaga> .CreatePessimistic( () => new SlowConcurrentSagaContextFactory().CreateDbContext(DbContextOptionsBuilder), notWorkingRowLockStatements)); _sagaTestHarness = BusTestHarness.StateMachineSaga(new SlowConcurrentSagaStateMachine(), _sagaRepository.Value); }
public Using_ef_connection_resiliency() { // add new migration by calling // dotnet ef migrations add --context "SagaDbContext``2" Init -v var contextFactory = new ContextFactoryWithResilienceStrategy(); using (var context = contextFactory.CreateDbContext(Array.Empty <string>())) { context.Database.Migrate(); } _sagaDbContextFactory = () => contextFactory.CreateDbContext(Array.Empty <string>()); _sagaRepository = new Lazy <ISagaRepository <SimpleSaga> >(() => EntityFrameworkSagaRepository <SimpleSaga> .CreatePessimistic(_sagaDbContextFactory)); }
public Locating_an_existing_ef_saga() { // add new migration by calling // dotnet ef migrations add --context "SagaDbContext``2" Init -v var contextFactory = new ContextFactory(); using (SagaDbContext <SimpleSaga, SimpleSagaMap> context = contextFactory.CreateDbContext(Array.Empty <string>())) { context.Database.Migrate(); } _sagaDbContextFactory = () => contextFactory.CreateDbContext(Array.Empty <string>()); _sagaRepository = new Lazy <ISagaRepository <SimpleSaga> >(() => EntityFrameworkSagaRepository <SimpleSaga> .CreatePessimistic(_sagaDbContextFactory)); }
private static void Run() { ISagaRepository <RegistrationStateInstance> sagaRepository = new EntityFrameworkSagaRepository <RegistrationStateInstance>(SagaDbContextFactory); IBusControl busControl = Bus.Factory.CreateUsingRabbitMq(cfg => { IRabbitMqHost host = cfg.Host(new Uri("rabbitmq://localhost"), h => { h.Username("guest"); h.Password("guest"); }); EndpointConvention.Map <IProcessRegistration>(new Uri("rabbitmq://localhost/registration.state.queue")); cfg.ReceiveEndpoint(host, "registration.state.queue", endpointConfigurator => { endpointConfigurator.PrefetchCount = 16; IPartitioner partitioner = cfg.CreatePartitioner(8); RegistrationStateMachine machine = new RegistrationStateMachine(); endpointConfigurator.StateMachineSaga(machine, sagaRepository, sagaConfigurator => { sagaConfigurator.Message <IRegistrationReceived>(m => m.UsePartitioner(partitioner, p => p.Message.SubmissionId)); sagaConfigurator.Message <IRegistrationCompleted>(m => m.UsePartitioner(partitioner, p => p.Message.SubmissionId)); }); }); }); busControl.StartAsync(); ReadKey(); busControl.StopAsync(); DbContext SagaDbContextFactory() { DbContextOptionsBuilder optionsBuilder = new DbContextOptionsBuilder(); optionsBuilder.UseSqlServer(@"Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=RegistrationDemo;Integrated Security=True"); SagaDbContext <RegistrationStateInstance, RegistrationStateInstanceMap> context = new SagaDbContext <RegistrationStateInstance, RegistrationStateInstanceMap>(optionsBuilder.Options); context.Database.EnsureCreated(); return(context); } }
public Using_custom_include_in_repository() { // add new migration by calling // dotnet ef migrations add --context "SagaWithDependencyContext" Init -v var contextFactory = new SagaWithDependencyContextFactory(); using (var context = contextFactory.CreateDbContext(Array.Empty <string>())) { context.Database.Migrate(); } _sagaDbContextFactory = () => contextFactory.CreateDbContext(Array.Empty <string>()); _sagaRepository = new Lazy <ISagaRepository <SagaWithDependency> >(() => EntityFrameworkSagaRepository <SagaWithDependency> .CreatePessimistic(_sagaDbContextFactory, queryCustomization: queryable => queryable.Include(it => it.Dependency).ThenInclude(dependency => dependency.SagaInnerDependency) )); }
static void Main(string[] args) { MapperMappings.Map(); var sagaStateMachine = new BookStateMachine(); string connectionString = ConfigurationManager.ConnectionStrings["sagabook"].ConnectionString; SagaDbContextFactory contextFactory = () => new SagaDbContext <Book, SagaInstanceMap>(connectionString); var repository = new EntityFrameworkSagaRepository <Book>(contextFactory, optimistic: true); var busControl = Bus.Factory.CreateUsingRabbitMq(x => { var host = x.Host(new Uri("rabbitmq://domer-ss/"), h => { h.Username("admin"); h.Password("admin"); }); x.ReceiveEndpoint(host, "book_guest", e => { e.StateMachineSaga(sagaStateMachine, repository); }); }); busControl.Start(); ConsoleKey consoleKey = ConsoleKey.NoName; do { if (consoleKey == ConsoleKey.F1) { busControl.Publish <Message1>(new { Message = "Hello World 1!" }); } if (consoleKey == ConsoleKey.F2) { busControl.Publish <Message2>(new { Message = "Hello World 2!" }); } } while ((consoleKey = Console.ReadKey().Key) != ConsoleKey.Escape); busControl.Stop(); }
protected override void ConfigureInMemoryReceiveEndpoint(IInMemoryReceiveEndpointConfigurator configurator) { _discarded = GetTask <bool>(); _simpleStateMachine = new SimpleStateMachine(x => { _discarded.TrySetResult(true); }); _sagaDbContextFactory = new DelegateSagaDbContextFactory <SimpleState>(() => new SimpleStateSagaDbContext(SagaDbContextFactoryProvider.GetLocalDbConnectionString())); _simpleStateRepository = new Lazy <ISagaRepository <SimpleState> >(() => EntityFrameworkSagaRepository <SimpleState> .CreatePessimistic(_sagaDbContextFactory)); configurator.StateMachineSaga(_simpleStateMachine, _simpleStateRepository.Value); base.ConfigureInMemoryReceiveEndpoint(configurator); }
public static void ConfigureBus(HostBuilderContext context, IServiceCollection services) { services.AddMassTransit(config => { config.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg => { var busConfig = context.Configuration.GetSection("Bus"); var host = cfg.ConfigureHost(busConfig); var connectionString = provider.GetRequiredService <IConfiguration>()["SagaStoreConnection"]; var optionsBuilder = new DbContextOptionsBuilder <SagaDbContext <SagaInstance, SagaInstanceMap> >(); optionsBuilder.UseSqlServer(connectionString, options => options.CommandTimeout(5)); DbContext contextFactory() => new SagaDbContext <SagaInstance, SagaInstanceMap>(optionsBuilder.Options); var repository = EntityFrameworkSagaRepository <SagaInstance> .CreateOptimistic(contextFactory); cfg.ReceiveEndpoint(host, "OrderWorkflow", e => { e.UseRetry(x => { x.Handle <DbUpdateConcurrencyException>(); // This is the SQLServer error code for duplicate key, if you are using another Relational Db, the code might be different x.Handle <DbUpdateException>(y => y.InnerException is SqlException ex && ex.Number == 2627); x.Interval(5, TimeSpan.FromMilliseconds(100)); }); e.UseFilter(new OperationContextFilter()); e.StateMachineSaga(new OrderSaga(provider.GetRequiredService <ILogger <OrderSaga> >()), repository); }); EndpointConvention.Map <CompleteOrder>(new Uri(new Uri(busConfig["Host"]), nameof(CompleteOrder))); EndpointConvention.Map <FailOrder>(new Uri(new Uri(busConfig["Host"]), nameof(FailOrder))); EndpointConvention.Map <Delivery.Commands.PlaceOrder>(new Uri(new Uri(busConfig["Host"]), "CreateDelivery")); contextFactory().Database.EnsureCreated(); })); }); services.AddSingleton <IHostedService, BusService>(); }
public BatchStateMachineTests() { var dbOptionsBuilder = new DbContextOptionsBuilder() .UseSqlServer(TestConstants.ConnectionString) .EnableSensitiveDataLogging(); _dbContextFactory = () => new SampleBatchDbContext(dbOptionsBuilder.Options); // Makes sure the DB is created for tests using (var db = _dbContextFactory()) { db.Database.EnsureCreated(); } _sagaRepository = EntityFrameworkSagaRepository <BatchState> .CreatePessimistic(_dbContextFactory, new CustomSqlLockStatementProvider("select * from {0}.{1} WITH (UPDLOCK, ROWLOCK) WHERE BatchId = @p0")); _stateMachine = new BatchStateMachine(); _inMemoryTestHarness = new InMemoryTestHarness(); _inMemoryConsumerHarness = _inMemoryTestHarness.Consumer <FakeBatchJobSagaConsumer>(Guid.NewGuid().ToString()); _inMemoryTestHarness.OnConfigureInMemoryReceiveEndpoint += ConfigureInMemoryReceiveEndpoint; _inMemoryTestHarness.OnConfigureInMemoryBus += ConfigureInMemoryBus; }
public static IRabbitMqBusFactoryConfigurator RegisterSaga <TStateMachineInstance>(this IRabbitMqBusFactoryConfigurator cfg, MassTransitStateMachine <TStateMachineInstance> sagaStateMachine, EntityFrameworkSagaRepository <TStateMachineInstance> sagaRepository) where TStateMachineInstance : class, SagaStateMachineInstance, new() { var queueName = $"{typeof(TStateMachineInstance).FullName}"; cfg.ReceiveEndpoint(queueName, e => { e.UseConcurrencyLimit(1); e.StateMachineSaga(sagaStateMachine, sagaRepository); }); return(cfg); }
public static void AddMassTransitWithRabbitMq(this IServiceCollection services, IConfiguration appConfig) { if (services == null) { throw new ArgumentNullException("services"); } if (appConfig == null) { throw new ArgumentNullException("appConfig"); } var cfgSection = appConfig.GetSection("RabbitMqHost"); if (!cfgSection.Exists()) { throw new InvalidOperationException("Appsettings: 'RabbitMqHost' section is not found"); } services.Configure <RabbitMqHostOptions>(cfgSection); var epSection = appConfig.GetSection("MqEndpoints"); if (!epSection.Exists()) { throw new InvalidOperationException("Appsettings: 'MqEndpoints' section was not found"); } services.Configure <MqEndpointOptions>(epSection); services.AddMassTransit(cfg => { cfg.AddConsumer <RoutingSlipMetricsConsumer>(); cfg.AddConsumer <RoutingSlipActivityConsumer>(); cfg.AddSaga <RoutingSlipState>(); }); services.AddSingleton <RoutingSlipStateMachine>(); services.AddSingleton(svcProv => { var fact = svcProv.GetService <ILoggerFactory>(); return(new RoutingSlipMetrics("Routing Slip", fact.CreateLogger <RoutingSlipMetrics>())); }); services.AddSingleton <ValidateActivityMatrics>(); services.AddScoped <RoutingSlipMetricsConsumer>(svcProv => { var metrics = svcProv.GetService <RoutingSlipMetrics>(); return(new RoutingSlipMetricsConsumer(metrics)); }); services.AddScoped(svcProv => { var metrics = svcProv.GetService <ValidateActivityMatrics>(); var epOpts = svcProv.GetService <IOptions <MqEndpointOptions> >().Value; return(new RoutingSlipActivityConsumer(metrics, epOpts.ActivityMetrics.ActivityName)); }); services.AddSingleton(svcProv => { var config = svcProv.GetService <IConfiguration>(); var conStr = config.GetConnectionString("EfCoreRoutingSlip"); return(new RoutingSlipDbContextFactory(conStr)); }); services.AddSingleton <ISagaRepository <RoutingSlipState>, EntityFrameworkSagaRepository <RoutingSlipState> >(svcProv => { var ctxFactory = svcProv.GetService <RoutingSlipDbContextFactory>(); return(EntityFrameworkSagaRepository <RoutingSlipState> .CreateOptimistic(() => ctxFactory.CreateDbContext(Array.Empty <string>()))); }); services.AddSingleton(svcProv => { var hostOpts = svcProv.GetService <IOptions <RabbitMqHostOptions> >().Value; var epOpts = svcProv.GetService <IOptions <MqEndpointOptions> >().Value; var machine = svcProv.GetService <RoutingSlipStateMachine>(); var repository = svcProv.GetService <ISagaRepository <RoutingSlipState> >(); return(Bus.Factory.CreateUsingRabbitMq(cfg => { var host = cfg.CreateHost(hostOpts); cfg.ReceiveEndpoint(host, epOpts.Metrics.QueueName, e => { e.PrefetchCount = epOpts.Metrics.PrefetchCount; e.UseRetry(r => r.None()); //e.LoadFrom(svcProv); e.Consumer <RoutingSlipMetricsConsumer>(svcProv); e.Consumer <RoutingSlipActivityConsumer>(svcProv); }); cfg.ReceiveEndpoint(host, epOpts.ActivityMetrics.QueueName, e => { e.PrefetchCount = epOpts.ActivityMetrics.PrefetchCount; e.UseRetry(r => r.None()); }); cfg.ReceiveEndpoint(host, epOpts.Saga.QueueName, e => { e.UseInMemoryOutbox(); e.PrefetchCount = 1; e.UseConcurrencyLimit(1); e.StateMachineSaga(machine, repository); }); cfg.UseSerilog(); })); }); }
static async Task Main(string[] args) { var bus = Bus.Factory.CreateUsingRabbitMq(cfg => { cfg.Host(new Uri(BASE_URI), c => { c.Username("guest"); c.Password("guest"); }); cfg.ReceiveEndpoint("mysaga", ec => { ec.UseInMemoryOutbox(); var _mySagaInstance = new MySaga(); //ISagaRepository<MySaga> repoCreateQuoteSaga = new InMemorySagaRepository<MySaga>(); ISagaRepository <MySaga> repoCreateQuoteSaga = EntityFrameworkSagaRepository <MySaga> .CreatePessimistic(() => { var options = new DbContextOptionsBuilder() .UseSqlServer(DB_CS, m => { object p = m.MigrationsAssembly(Assembly.GetExecutingAssembly().GetName().Name); m.MigrationsHistoryTable($"__MySaga"); }) .Options; var dbContext = new MySagaDbContext(options); return(dbContext); }); ec.Saga(repoCreateQuoteSaga); }); }); using var cancelation = new CancellationTokenSource(TimeSpan.FromSeconds(30)); await bus.StartAsync(cancelation.Token); try { await Console.Out.WriteLineAsync("Press any key to exit..."); await Task.Run(Console.ReadKey); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } finally { try { bus.Stop(); } catch (Exception e) { Console.WriteLine(e.Message); } } }
ISagaRepository<ReadOnlyInstance> CreateSagaRepository() { return EntityFrameworkSagaRepository<ReadOnlyInstance>.CreatePessimistic( () => new ReadOnlySagaDbContextFactory().CreateDbContext(DbContextOptionsBuilder), RawSqlLockStatements); }