using BuildingBlocks.EventStoreDB.Events; using BuildingBlocks.EventStoreDB.Serialization; using EventStore.Client; namespace BuildingBlocks.EventStoreDB.Repository; public interface IEventStoreDBRepository where T : class, IAggregateEventSourcing { Task Find(Guid id, CancellationToken cancellationToken); Task Add(T aggregate, CancellationToken cancellationToken); Task Update(T aggregate, long? expectedRevision = null, CancellationToken cancellationToken = default); Task Delete(T aggregate, long? expectedRevision = null, CancellationToken cancellationToken = default); } public class EventStoreDBRepository : IEventStoreDBRepository where T : class, IAggregateEventSourcing { private static readonly long _currentUserId; private readonly EventStoreClient eventStore; public EventStoreDBRepository(EventStoreClient eventStore) { this.eventStore = eventStore ?? throw new ArgumentNullException(nameof(eventStore)); } public Task Find(Guid id, CancellationToken cancellationToken) { return eventStore.AggregateStream( id, cancellationToken ); } public async Task Add(T aggregate, CancellationToken cancellationToken = default) { var result = await eventStore.AppendToStreamAsync( StreamNameMapper.ToStreamId(aggregate.Id), StreamState.NoStream, GetEventsToStore(aggregate), cancellationToken: cancellationToken ); return result.NextExpectedStreamRevision; } public async Task Update(T aggregate, long? expectedRevision = null, CancellationToken cancellationToken = default) { var nextVersion = expectedRevision ?? aggregate.Version; var result = await eventStore.AppendToStreamAsync( StreamNameMapper.ToStreamId(aggregate.Id), (ulong)nextVersion, GetEventsToStore(aggregate), cancellationToken: cancellationToken ); return result.NextExpectedStreamRevision; } public Task Delete(T aggregate, long? expectedRevision = null, CancellationToken cancellationToken = default) { return Update(aggregate, expectedRevision, cancellationToken); } private static IEnumerable GetEventsToStore(T aggregate) { var events = aggregate.ClearDomainEvents(); return events .Select(EventStoreDBSerializer.ToJsonEventData); } }