using FictionArchive.Service.Shared.MassTransit.Configuration; using MassTransit; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace FictionArchive.Service.Shared.MassTransit; public static class MassTransitExtensions { /// /// Adds MassTransit with RabbitMQ and Entity Framework outbox /// public static IServiceCollection AddFictionArchiveMassTransit( this IServiceCollection services, IConfiguration configuration, Action? configureConsumers = null) where TDbContext : DbContext { services.AddMassTransit(x => { configureConsumers?.Invoke(x); x.AddEntityFrameworkOutbox(o => { o.UsePostgres(); o.UseBusOutbox(); }); x.UsingRabbitMq((context, cfg) => { var options = configuration.GetSection("RabbitMQ").Get() ?? new MassTransitOptions(); cfg.Host(options.Host, options.VirtualHost, h => { h.Username(options.Username); h.Password(options.Password); }); // Immediate retries for transient failures cfg.UseMessageRetry(r => r.Intervals( TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))); // Delayed redelivery for longer outages cfg.UseDelayedRedelivery(r => r.Intervals( TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(30), TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(30))); cfg.ConfigureEndpoints(context); }); }); return services; } /// /// Adds MassTransit with RabbitMQ without outbox (for services without EF) /// public static IServiceCollection AddFictionArchiveMassTransit( this IServiceCollection services, IConfiguration configuration, Action? configureConsumers = null) { services.AddMassTransit(x => { configureConsumers?.Invoke(x); x.UsingRabbitMq((context, cfg) => { var options = configuration.GetSection("RabbitMQ").Get() ?? new MassTransitOptions(); cfg.Host(options.Host, options.VirtualHost, h => { h.Username(options.Username); h.Password(options.Password); }); cfg.UseMessageRetry(r => r.Intervals( TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))); cfg.UseDelayedRedelivery(r => r.Intervals( TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(30), TimeSpan.FromMinutes(2), TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(30))); cfg.ConfigureEndpoints(context); }); }); return services; } }