dotnet-cqrs/Svrnty.CQRS.Events.Abstractions/Projections/IProjectionRegistry.cs

146 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
namespace Svrnty.CQRS.Events.Abstractions.Projections;
/// <summary>
/// Registry for managing projection definitions and their configurations.
/// </summary>
/// <remarks>
/// <para>
/// <strong>Phase 7 Feature - Projection Registry:</strong>
/// The registry maintains metadata about all registered projections,
/// including which streams they consume and how they should be executed.
/// </para>
/// </remarks>
public interface IProjectionRegistry
{
/// <summary>
/// Registers a projection with the registry.
/// </summary>
/// <param name="definition">The projection definition.</param>
void Register(ProjectionDefinition definition);
/// <summary>
/// Gets a projection definition by name.
/// </summary>
/// <param name="projectionName">The unique name of the projection.</param>
/// <returns>The projection definition, or null if not found.</returns>
ProjectionDefinition? GetProjection(string projectionName);
/// <summary>
/// Gets all registered projection definitions.
/// </summary>
/// <returns>All projection definitions.</returns>
IEnumerable<ProjectionDefinition> GetAllProjections();
/// <summary>
/// Gets all projections that consume from a specific stream.
/// </summary>
/// <param name="streamName">The name of the stream.</param>
/// <returns>All projection definitions consuming from this stream.</returns>
IEnumerable<ProjectionDefinition> GetProjectionsForStream(string streamName);
}
/// <summary>
/// Defines a projection's configuration and behavior.
/// </summary>
public sealed record ProjectionDefinition
{
/// <summary>
/// The unique name of the projection.
/// </summary>
public required string ProjectionName { get; init; }
/// <summary>
/// The name of the stream to consume from.
/// </summary>
public required string StreamName { get; init; }
/// <summary>
/// The type of the projection implementation.
/// </summary>
public required Type ProjectionType { get; init; }
/// <summary>
/// The type of events this projection handles.
/// </summary>
/// <remarks>
/// Null if projection implements IDynamicProjection and handles multiple event types.
/// </remarks>
public Type? EventType { get; init; }
/// <summary>
/// Execution options for the projection.
/// </summary>
public ProjectionOptions Options { get; init; } = new();
/// <summary>
/// Optional description of what this projection does.
/// </summary>
public string? Description { get; init; }
}
/// <summary>
/// Configuration options for projection execution.
/// </summary>
public sealed record ProjectionOptions
{
/// <summary>
/// Number of events to read from stream per batch.
/// </summary>
/// <remarks>
/// Default: 100. Larger batches = higher throughput but more memory.
/// </remarks>
public int BatchSize { get; set; } = 100;
/// <summary>
/// Whether to start the projection automatically on application startup.
/// </summary>
/// <remarks>
/// Default: true. Set to false for projections that should be started manually.
/// </remarks>
public bool AutoStart { get; set; } = true;
/// <summary>
/// Maximum number of retry attempts for failed events.
/// </summary>
/// <remarks>
/// Default: 3. After max retries, the projection moves to Failed state.
/// </remarks>
public int MaxRetries { get; set; } = 3;
/// <summary>
/// Base delay for exponential backoff retry strategy.
/// </summary>
/// <remarks>
/// Default: 1 second. Actual delay = BaseRetryDelay * 2^(attemptNumber).
/// </remarks>
public TimeSpan BaseRetryDelay { get; set; } = TimeSpan.FromSeconds(1);
/// <summary>
/// How often to poll for new events when caught up.
/// </summary>
/// <remarks>
/// Default: 1 second. Shorter = more responsive, longer = less database load.
/// </remarks>
public TimeSpan PollingInterval { get; set; } = TimeSpan.FromSeconds(1);
/// <summary>
/// Whether to checkpoint after each event or only after each batch.
/// </summary>
/// <remarks>
/// Default: false (checkpoint per batch). Set to true for exactly-once semantics
/// at the cost of higher checkpoint overhead.
/// </remarks>
public bool CheckpointPerEvent { get; set; } = false;
/// <summary>
/// Whether this projection can be reset and rebuilt.
/// </summary>
/// <remarks>
/// Default: true. Set to false to prevent accidental rebuilds of critical projections.
/// </remarks>
public bool AllowRebuild { get; set; } = true;
}