188 lines
6.1 KiB
C#
188 lines
6.1 KiB
C#
using System;
|
|
using Svrnty.CQRS.Events.Abstractions.EventStore;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Svrnty.CQRS.Events.Abstractions.Models;
|
|
|
|
/// <summary>
|
|
/// Wraps a command result with events to be emitted.
|
|
/// The framework automatically handles correlation ID assignment and event emission.
|
|
/// </summary>
|
|
/// <typeparam name="TResult">The type of the command result.</typeparam>
|
|
public sealed class CommandResultWithEvents<TResult>
|
|
{
|
|
private readonly List<ICorrelatedEvent> _events = new();
|
|
|
|
/// <summary>
|
|
/// The result of the command execution.
|
|
/// </summary>
|
|
public TResult Result { get; }
|
|
|
|
/// <summary>
|
|
/// Events to be emitted with automatic correlation ID management.
|
|
/// </summary>
|
|
public IReadOnlyList<ICorrelatedEvent> Events => _events.AsReadOnly();
|
|
|
|
/// <summary>
|
|
/// Correlation ID assigned by the framework.
|
|
/// Available after the command is processed.
|
|
/// This setter is public for framework use but should not be set by application code.
|
|
/// </summary>
|
|
public string? CorrelationId { get; set; }
|
|
|
|
public CommandResultWithEvents(TResult result)
|
|
{
|
|
Result = result;
|
|
}
|
|
|
|
public CommandResultWithEvents(TResult result, params ICorrelatedEvent[] events)
|
|
{
|
|
Result = result;
|
|
_events.AddRange(events);
|
|
}
|
|
|
|
public CommandResultWithEvents(TResult result, IEnumerable<ICorrelatedEvent> events)
|
|
{
|
|
Result = result;
|
|
_events.AddRange(events);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an event to be emitted. The correlation ID will be automatically assigned.
|
|
/// </summary>
|
|
public CommandResultWithEvents<TResult> AddEvent(ICorrelatedEvent @event)
|
|
{
|
|
_events.Add(@event);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add multiple events to be emitted. Correlation IDs will be automatically assigned.
|
|
/// </summary>
|
|
public CommandResultWithEvents<TResult> AddEvents(params ICorrelatedEvent[] events)
|
|
{
|
|
_events.AddRange(events);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add multiple events to be emitted. Correlation IDs will be automatically assigned.
|
|
/// </summary>
|
|
public CommandResultWithEvents<TResult> AddEvents(IEnumerable<ICorrelatedEvent> events)
|
|
{
|
|
_events.AddRange(events);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method used by the framework to assign correlation IDs to all events.
|
|
/// This method is public for framework use but should not be called by application code.
|
|
/// </summary>
|
|
public void AssignCorrelationIds(string correlationId)
|
|
{
|
|
CorrelationId = correlationId;
|
|
|
|
foreach (var @event in _events)
|
|
{
|
|
// Use reflection to set the correlation ID
|
|
var correlationIdProperty = @event.GetType().GetProperty(nameof(ICorrelatedEvent.CorrelationId));
|
|
if (correlationIdProperty != null && correlationIdProperty.CanWrite)
|
|
{
|
|
correlationIdProperty.SetValue(@event, correlationId);
|
|
}
|
|
else if (correlationIdProperty != null && correlationIdProperty.GetSetMethod(nonPublic: true) != null)
|
|
{
|
|
// Handle init-only properties
|
|
correlationIdProperty.GetSetMethod(nonPublic: true)!.Invoke(@event, new object[] { correlationId });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wraps events to be emitted for commands that don't return a result.
|
|
/// The framework automatically handles correlation ID assignment and event emission.
|
|
/// </summary>
|
|
public sealed class CommandResultWithEvents
|
|
{
|
|
private readonly List<ICorrelatedEvent> _events = new();
|
|
|
|
/// <summary>
|
|
/// Events to be emitted with automatic correlation ID management.
|
|
/// </summary>
|
|
public IReadOnlyList<ICorrelatedEvent> Events => _events.AsReadOnly();
|
|
|
|
/// <summary>
|
|
/// Correlation ID assigned by the framework.
|
|
/// Available after the command is processed.
|
|
/// This setter is public for framework use but should not be set by application code.
|
|
/// </summary>
|
|
public string? CorrelationId { get; set; }
|
|
|
|
public CommandResultWithEvents()
|
|
{
|
|
}
|
|
|
|
public CommandResultWithEvents(params ICorrelatedEvent[] events)
|
|
{
|
|
_events.AddRange(events);
|
|
}
|
|
|
|
public CommandResultWithEvents(IEnumerable<ICorrelatedEvent> events)
|
|
{
|
|
_events.AddRange(events);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an event to be emitted. The correlation ID will be automatically assigned.
|
|
/// </summary>
|
|
public CommandResultWithEvents AddEvent(ICorrelatedEvent @event)
|
|
{
|
|
_events.Add(@event);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add multiple events to be emitted. Correlation IDs will be automatically assigned.
|
|
/// </summary>
|
|
public CommandResultWithEvents AddEvents(params ICorrelatedEvent[] events)
|
|
{
|
|
_events.AddRange(events);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add multiple events to be emitted. Correlation IDs will be automatically assigned.
|
|
/// </summary>
|
|
public CommandResultWithEvents AddEvents(IEnumerable<ICorrelatedEvent> events)
|
|
{
|
|
_events.AddRange(events);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method used by the framework to assign correlation IDs to all events.
|
|
/// This method is public for framework use but should not be called by application code.
|
|
/// </summary>
|
|
public void AssignCorrelationIds(string correlationId)
|
|
{
|
|
CorrelationId = correlationId;
|
|
|
|
foreach (var @event in _events)
|
|
{
|
|
// Use reflection to set the correlation ID
|
|
var correlationIdProperty = @event.GetType().GetProperty(nameof(ICorrelatedEvent.CorrelationId));
|
|
if (correlationIdProperty != null && correlationIdProperty.CanWrite)
|
|
{
|
|
correlationIdProperty.SetValue(@event, correlationId);
|
|
}
|
|
else if (correlationIdProperty != null && correlationIdProperty.GetSetMethod(nonPublic: true) != null)
|
|
{
|
|
// Handle init-only properties
|
|
correlationIdProperty.GetSetMethod(nonPublic: true)!.Invoke(@event, new object[] { correlationId });
|
|
}
|
|
}
|
|
}
|
|
}
|