Interface IAggregationService
- Namespace
- Stratara.Abstractions.EventSourcing
- Assembly
- Stratara.Abstractions.dll
Reconstructs an aggregate by reading its event stream + applying events. Command handlers and sagas use this — never read aggregates from projection views.
public interface IAggregationService
- Extension Methods
Examples
Rehydrate an aggregate in a command handler, then apply a mutation:
public sealed class ShipOrderHandler(IAggregationService aggregator, IEventSource events)
: ICommandHandler<ShipOrder>
{
public async Task HandleAsync(ShipOrder command, CancellationToken cancellationToken)
{
var order = await aggregator.AggregateAsync<Order>(command.OrderId, cancellationToken: cancellationToken)
?? throw new InvalidOperationException($"Order {command.OrderId} not found.");
await events.AppendAsync<Order>(order.Id, new OrderShipped(order.Id, DateTimeOffset.UtcNow),
cancellationToken);
await events.SaveChangesAsync(cancellationToken);
}
}
Remarks
Tenant ownership: handlers operating on ITenantAggregates should prefer the
AggregateOwnedByTenantAsync<TAggregate>(IAggregationService, Guid, Guid, CancellationToken)
extension, which returns null on either "not found" or "wrong tenant" — the
handler can then map both to NotFound without leaking foreign-tenant existence.
Methods
AggregateAsync(Type, Guid, long?, long?, CancellationToken)
Reflection-based variant for when the aggregate type is known only at runtime (replay tooling, generic admin endpoints).
Task<object?> AggregateAsync(Type aggregateType, Guid streamId, long? fromVersion = null, long? toVersion = null, CancellationToken cancellationToken = default)
Parameters
aggregateTypeTypeThe aggregate type to construct.
streamIdGuidThe aggregate's stream id.
fromVersionlong?Inclusive start version, or
nullfor stream start.toVersionlong?Inclusive end version, or
nullfor stream head.cancellationTokenCancellationTokenPropagated to the read-store query.
Returns
AggregateAsync<TAggregate>(Guid, long?, long?, CancellationToken)
Reconstruct an aggregate of TAggregate from
streamId's event stream.
Task<TAggregate?> AggregateAsync<TAggregate>(Guid streamId, long? fromVersion = null, long? toVersion = null, CancellationToken cancellationToken = default) where TAggregate : notnull, new()
Parameters
streamIdGuidThe aggregate's stream id.
fromVersionlong?Inclusive start version, or
nullfor stream start.toVersionlong?Inclusive end version, or
nullfor stream head.cancellationTokenCancellationTokenPropagated to the read-store query.
Returns
- Task<TAggregate>
The reconstructed aggregate, or
nullif the stream does not exist.
Type Parameters
TAggregateThe aggregate type — must have a parameterless constructor.