using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Svrnty.CQRS.Configuration; using Svrnty.CQRS.Sagas.Abstractions; using Svrnty.CQRS.Sagas.Abstractions.Persistence; using Svrnty.CQRS.Sagas.Configuration; using Svrnty.CQRS.Sagas.Persistence; namespace Svrnty.CQRS.Sagas; /// /// Extensions for adding saga support to the CQRS pipeline. /// public static class CqrsBuilderExtensions { /// /// Adds saga orchestration support to the CQRS pipeline. /// /// The CQRS builder. /// Optional configuration action. /// The CQRS builder for chaining. public static CqrsBuilder AddSagas(this CqrsBuilder builder, Action? configure = null) { var options = new SagaOptions(); configure?.Invoke(options); builder.Services.Configure(opt => { opt.DefaultStepTimeout = options.DefaultStepTimeout; opt.DefaultMaxRetries = options.DefaultMaxRetries; opt.DefaultRetryDelay = options.DefaultRetryDelay; opt.AutoCompensateOnFailure = options.AutoCompensateOnFailure; opt.StalledSagaCheckInterval = options.StalledSagaCheckInterval; opt.StepStalledTimeout = options.StepStalledTimeout; }); // Store configuration builder.Configuration.SetConfiguration(options); // Register core saga services builder.Services.TryAddSingleton(); // Register default in-memory state store if not already registered builder.Services.TryAddSingleton(); return builder; } /// /// Registers a saga type with the CQRS pipeline. /// /// The saga type. /// The saga data type. /// The CQRS builder. /// The CQRS builder for chaining. public static CqrsBuilder AddSaga(this CqrsBuilder builder) where TSaga : class, ISaga where TData : class, ISagaData, new() { builder.Services.AddTransient(); builder.Services.AddTransient, TSaga>(); return builder; } /// /// Uses a custom saga state store implementation. /// /// The state store implementation type. /// The CQRS builder. /// The CQRS builder for chaining. public static CqrsBuilder UseSagaStateStore(this CqrsBuilder builder) where TStore : class, ISagaStateStore { // Remove existing registration var descriptor = new ServiceDescriptor(typeof(ISagaStateStore), typeof(TStore), ServiceLifetime.Singleton); builder.Services.Replace(descriptor); return builder; } }