/// <summary> /// Persists the state of the specified aggregate by adding new events to the event store. /// </summary> /// <param name="aggregate">The aggregate to persist.</param> public async Task Save(TAggregate aggregate) { var events = aggregate.PendingEvents.ToArray(); foreach (var e in events) { await eventStream.Append(new[] { e.ToStoredEvent() }); e.SetAggregate(aggregate); } var pendingRenames = aggregate.IfTypeIs <IEventMigratingAggregate>() .Then(_ => _.PendingRenames) .ElseDefault() .OrEmpty(); foreach (var rename in pendingRenames) { var eventToRename = eventStream.Events.SingleOrDefault(e => e.AggregateId == aggregate.Id.ToString() && e.SequenceNumber == rename.SequenceNumber); if (eventToRename == null) { throw new EventMigrations.SequenceNumberNotFoundException(aggregate.Id, rename.SequenceNumber); } eventToRename.Type = rename.NewName; } aggregate.ConfirmSave(); // publish the events await bus.PublishAsync(events); }
async Task Save(TAggregate aggregate, IEnumerable <EventMigrator.Rename> pendingRenames) { var events = aggregate.PendingEvents.ToArray(); foreach (var e in events) { await eventStream.Append(new[] { e.ToStoredEvent() }); e.SetAggregate(aggregate); } foreach (var rename in pendingRenames) { var eventToRename = eventStream.Events.SingleOrDefault(e => e.AggregateId == aggregate.Id.ToString() && e.SequenceNumber == rename.SequenceNumber); if (eventToRename == null) { throw new EventMigrator.SequenceNumberNotFoundException(aggregate.Id, rename.SequenceNumber); } eventToRename.Type = rename.NewName; } aggregate.IfTypeIs <EventSourcedAggregate>() .ThenDo(a => a.ConfirmSave()); // publish the events await bus.PublishAsync(events); }
internal static IEventStream ToEventStream(this IEnumerable <IEvent> events, string name) { var stream = new InMemoryEventStream(name); var storableEvents = events.AssignSequenceNumbers() .Select(e => e.ToStoredEvent()); stream.Append(storableEvents.ToArray()) .Wait(); return(stream); }
private async Task AssignIdsAndSyncStream() { var newEvents = sqlEvents .Select(e => new { inMemoryEvent = e.ToInMemoryStoredEvent(), sqlEvent = e }) .Where(ee => !eventStream.Contains(ee.inMemoryEvent)) .ToArray(); newEvents.ForEach(e => { var nextId = Interlocked.Increment(ref eventStream.NextAbsoluteSequenceNumber); e.inMemoryEvent.Metadata.AbsoluteSequenceNumber = nextId; e.sqlEvent.Id = nextId; }); await eventStream.Append(newEvents.Select(_ => _.inMemoryEvent).ToArray()); }
private async Task AssignIdsAndSyncStream() { foreach (var pendingEvent in eventsDbSet.Pending) { if (persistedEventsStream.Any( e => Guid.Parse(e.AggregateId) == pendingEvent.AggregateId && e.SequenceNumber == pendingEvent.SequenceNumber)) { eventsDbSet.CancelChanges(); throw new DbUpdateConcurrencyException(); } var nextId = Interlocked.Increment(ref persistedEventsStream.NextAbsoluteSequenceNumber); pendingEvent.Id = nextId; } await persistedEventsStream.Append( eventsDbSet.Pending .Select(_ => _.ToInMemoryStoredEvent()) .ToArray()); eventsDbSet.CommitChanges(); }