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

158 lines
6.6 KiB
C#

using System;
using Svrnty.CQRS.Events.ConsumerGroups.PostgreSQL;
using Svrnty.CQRS.Events.ConsumerGroups.Monitoring;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Svrnty.CQRS.Events.ConsumerGroups.Abstractions;
namespace Svrnty.CQRS.Events.ConsumerGroups;
/// <summary>
/// Extension methods for registering consumer group services.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds PostgreSQL-based consumer group support with health monitoring.
/// Registers IConsumerOffsetStore, IConsumerGroupReader, and the health monitor background service.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="configureStorage">Action to configure PostgreSQL storage options.</param>
/// <param name="configureHealthMonitor">Optional action to configure health monitor options.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddPostgresConsumerGroups(
this IServiceCollection services,
Action<PostgresConsumerGroupOptions> configureStorage,
Action<ConsumerHealthMonitorOptions>? configureHealthMonitor = null)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (configureStorage == null)
throw new ArgumentNullException(nameof(configureStorage));
// Configure storage options
services.Configure(configureStorage);
// Configure health monitor options (if provided)
if (configureHealthMonitor != null)
{
services.Configure(configureHealthMonitor);
}
// Register core services
services.TryAddSingleton<IConsumerOffsetStore, PostgresConsumerOffsetStore>();
services.TryAddSingleton<IConsumerGroupReader, PostgresConsumerGroupReader>();
// Register health monitor as hosted service
services.AddHostedService<ConsumerHealthMonitor>();
return services;
}
/// <summary>
/// Adds PostgreSQL-based consumer group support with health monitoring.
/// Registers IConsumerOffsetStore, IConsumerGroupReader, and the health monitor background service.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="storageConfiguration">Configuration section for PostgreSQL storage options.</param>
/// <param name="healthMonitorConfiguration">Optional configuration section for health monitor options.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddPostgresConsumerGroups(
this IServiceCollection services,
IConfigurationSection storageConfiguration,
IConfigurationSection? healthMonitorConfiguration = null)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (storageConfiguration == null)
throw new ArgumentNullException(nameof(storageConfiguration));
// Configure storage options from configuration
services.Configure<PostgresConsumerGroupOptions>(options => storageConfiguration.Bind(options));
// Configure health monitor options from configuration (if provided)
if (healthMonitorConfiguration != null)
{
services.Configure<ConsumerHealthMonitorOptions>(options => healthMonitorConfiguration.Bind(options));
}
// Register core services
services.TryAddSingleton<IConsumerOffsetStore, PostgresConsumerOffsetStore>();
services.TryAddSingleton<IConsumerGroupReader, PostgresConsumerGroupReader>();
// Register health monitor as hosted service
services.AddHostedService<ConsumerHealthMonitor>();
return services;
}
/// <summary>
/// Adds consumer offset store implementation.
/// Use this if you only need offset tracking without the full consumer group reader.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="configureStorage">Action to configure PostgreSQL storage options.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddPostgresConsumerOffsetStore(
this IServiceCollection services,
Action<PostgresConsumerGroupOptions> configureStorage)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (configureStorage == null)
throw new ArgumentNullException(nameof(configureStorage));
services.Configure(configureStorage);
services.TryAddSingleton<IConsumerOffsetStore, PostgresConsumerOffsetStore>();
return services;
}
/// <summary>
/// Adds consumer offset store implementation.
/// Use this if you only need offset tracking without the full consumer group reader.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="storageConfiguration">Configuration section for PostgreSQL storage options.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddPostgresConsumerOffsetStore(
this IServiceCollection services,
IConfigurationSection storageConfiguration)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (storageConfiguration == null)
throw new ArgumentNullException(nameof(storageConfiguration));
services.Configure<PostgresConsumerGroupOptions>(options => storageConfiguration.Bind(options));
services.TryAddSingleton<IConsumerOffsetStore, PostgresConsumerOffsetStore>();
return services;
}
/// <summary>
/// Adds the consumer health monitor background service.
/// Requires IConsumerOffsetStore to be registered.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="configure">Optional action to configure health monitor options.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddConsumerHealthMonitor(
this IServiceCollection services,
Action<ConsumerHealthMonitorOptions>? configure = null)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (configure != null)
{
services.Configure(configure);
}
services.AddHostedService<ConsumerHealthMonitor>();
return services;
}
}