dotnet-cqrs/Svrnty.CQRS.Events/Subscriptions/ServiceCollectionExtensions.cs

91 lines
4.0 KiB
C#

using System;
using Svrnty.CQRS.Events.Abstractions.Delivery;
using Svrnty.CQRS.Events.Delivery;
using Svrnty.CQRS.Events.Abstractions.EventStore;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Svrnty.CQRS.Events.Abstractions;
using Svrnty.CQRS.Events.Abstractions.Subscriptions;
namespace Svrnty.CQRS.Events.Subscriptions;
/// <summary>
/// Service collection extensions for persistent subscriptions.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Add persistent subscription support to the service collection.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="useInMemoryStore">If true, uses in-memory store. Otherwise, expects a persistent store to be registered separately.</param>
/// <param name="enableBackgroundDelivery">If true, enables background service for automatic event delivery to subscriptions.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddPersistentSubscriptions(
this IServiceCollection services,
bool useInMemoryStore = true,
bool enableBackgroundDelivery = true)
{
// Register subscription manager
services.AddSingleton<ISubscriptionManager, SubscriptionManager>();
// Register Phase 8 event delivery service
services.AddSingleton<IPersistentSubscriptionDeliveryService, EventDeliveryService>();
// Register in-memory store if requested
if (useInMemoryStore)
{
services.AddSingleton<IPersistentSubscriptionStore, InMemorySubscriptionStore>();
}
// Decorate the main IEventDeliveryService with Phase 8 integration
// This wraps the existing event delivery to also notify persistent subscriptions
DecorateEventDeliveryService(services);
// Register background delivery service if requested
// NOTE: SubscriptionDeliveryHostedService is temporarily disabled pending redesign
// to work with ICorrelatedEvent which doesn't have Sequence/EventType properties
// if (enableBackgroundDelivery)
// {
// services.AddHostedService<SubscriptionDeliveryHostedService>();
// }
return services;
}
private static void DecorateEventDeliveryService(IServiceCollection services)
{
// Find the existing IEventDeliveryService registration
var existingDescriptor = services.FirstOrDefault(d => d.ServiceType == typeof(IEventDeliveryService));
if (existingDescriptor == null)
{
// If not registered yet, this will be called before AddSvrntyEvents
// The decorator will be registered anyway and will work when the service is added
return;
}
// Remove the existing registration
services.Remove(existingDescriptor);
// Re-register the original implementation with a different service type
services.Add(ServiceDescriptor.Describe(
typeof(Svrnty.CQRS.Events.Delivery.EventDeliveryService),
existingDescriptor.ImplementationType!,
existingDescriptor.Lifetime));
// Register the decorator as IEventDeliveryService
services.Add(ServiceDescriptor.Describe(
typeof(IEventDeliveryService),
sp =>
{
var inner = sp.GetRequiredService<Svrnty.CQRS.Events.Delivery.EventDeliveryService>();
var persistentDeliveryService = sp.GetService<IPersistentSubscriptionDeliveryService>();
var subscriptionStore = sp.GetService<IPersistentSubscriptionStore>();
var logger = sp.GetRequiredService<Microsoft.Extensions.Logging.ILogger<PersistentSubscriptionDeliveryDecorator>>();
return new PersistentSubscriptionDeliveryDecorator(inner, persistentDeliveryService, subscriptionStore, logger);
},
existingDescriptor.Lifetime));
}
}