94 lines
3.6 KiB
C#
94 lines
3.6 KiB
C#
using System.Threading;
|
|
using Svrnty.CQRS.Events.Abstractions.EventStore;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Svrnty.CQRS.Events.Abstractions.Projections;
|
|
|
|
/// <summary>
|
|
/// Represents a projection that processes events to build a read model.
|
|
/// </summary>
|
|
/// <typeparam name="TEvent">The type of event this projection handles.</typeparam>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// <strong>Phase 7 Feature - Event Sourcing Projections:</strong>
|
|
/// Projections consume events from streams and build queryable read models.
|
|
/// Each projection maintains a checkpoint to track its position in the stream.
|
|
/// </para>
|
|
/// <para>
|
|
/// <strong>Key Concepts:</strong>
|
|
/// - Projections are idempotent (can process same event multiple times safely)
|
|
/// - Projections can be rebuilt by replaying events from the beginning
|
|
/// - Multiple projections can consume the same stream independently
|
|
/// - Projections run asynchronously and eventually consistent with the stream
|
|
/// </para>
|
|
/// </remarks>
|
|
public interface IProjection<in TEvent> where TEvent : ICorrelatedEvent
|
|
{
|
|
/// <summary>
|
|
/// Handles an event and updates the read model accordingly.
|
|
/// </summary>
|
|
/// <param name="event">The event to process.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>A task representing the async operation.</returns>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// This method should be idempotent - processing the same event multiple times
|
|
/// should produce the same result. This is critical for projection rebuilding.
|
|
/// </para>
|
|
/// <para>
|
|
/// If this method throws an exception, the projection engine will retry based on
|
|
/// its configured retry policy. Persistent failures may require manual intervention.
|
|
/// </para>
|
|
/// </remarks>
|
|
Task HandleAsync(TEvent @event, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a projection that can handle any event type dynamically.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Use this interface when you need to handle multiple event types in a single projection
|
|
/// or when event types are not known at compile time.
|
|
/// </remarks>
|
|
public interface IDynamicProjection
|
|
{
|
|
/// <summary>
|
|
/// Handles an event dynamically and updates the read model accordingly.
|
|
/// </summary>
|
|
/// <param name="event">The event to process.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>A task representing the async operation.</returns>
|
|
Task HandleAsync(ICorrelatedEvent @event, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Marker interface for projections that support rebuilding.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// Projections implementing this interface can be rebuilt from scratch by:
|
|
/// 1. Calling ResetAsync() to clear the read model
|
|
/// 2. Replaying all events from the beginning
|
|
/// 3. Processing events through HandleAsync()
|
|
/// </para>
|
|
/// <para>
|
|
/// This is useful for:
|
|
/// - Fixing bugs in projection logic
|
|
/// - Schema migrations in the read model
|
|
/// - Adding new projections to existing streams
|
|
/// </para>
|
|
/// </remarks>
|
|
public interface IResettableProjection
|
|
{
|
|
/// <summary>
|
|
/// Resets the projection's read model to its initial state.
|
|
/// </summary>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>A task representing the async operation.</returns>
|
|
/// <remarks>
|
|
/// This method should delete or clear all data in the read model.
|
|
/// After calling this, the projection can be rebuilt from offset 0.
|
|
/// </remarks>
|
|
Task ResetAsync(CancellationToken cancellationToken = default);
|
|
}
|