/// <summary> /// Call <see cref="IEventStore.SaveAsync"/> in <see cref="IEventStore"/> passing serialized events. /// </summary> public virtual async Task CommitAsync() { _logger.LogInformation($"Called method: {nameof(Session)}.{nameof(CommitAsync)}."); var aggregatesWithCommits = Aggregates.Where(x => x.UncommitedEvents.Count > 0).ToList(); AssertNoDuplicateCommits(aggregatesWithCommits); if (!_transactionStarted) { _eventStore.BeginTransaction(); } try { _logger.LogDebug("Serializing events."); var uncommitedEvents = aggregatesWithCommits.SelectMany(e => e.UncommitedEvents) .OrderBy(o => o.CreatedAt) .Cast <UncommitedEvent>() .ToList(); var serializedEvents = uncommitedEvents.Select(uncommitedEvent => { var metadata = _metadataProviders.SelectMany(md => md.Provide(uncommitedEvent.Aggregate, uncommitedEvent.OriginalEvent, Metadata.Empty)).Concat(new[] { new KeyValuePair <string, object>(MetadataKeys.EventId, Guid.NewGuid()), new KeyValuePair <string, object>(MetadataKeys.EventVersion, uncommitedEvent.Version) }); var serializedEvent = _eventSerializer.Serialize(uncommitedEvent.OriginalEvent, metadata); return(serializedEvent); }).ToList(); _logger.LogDebug("Saving events on Event Store."); await _eventStore.SaveAsync(serializedEvents).ConfigureAwait(false); _logger.LogDebug("Begin iterate in collection of stream."); foreach (var aggregate in _aggregateTracker.Aggregates) { _logger.LogDebug($"Update stream's version from {aggregate.Version} to {aggregate.UncommittedVersion}."); aggregate.SetVersion(aggregate.UncommittedVersion); aggregate.ClearUncommitedEvents(); _logger.LogDebug($"Scanning projection providers for {aggregate.GetType().Name}."); } _logger.LogInformation($"Publishing events. [Qty: {uncommitedEvents.Count}]"); await _eventPublisher.EnqueueAsync(uncommitedEvents.Select(e => e.OriginalEvent)).ConfigureAwait(false); _logger.LogDebug("Published events."); _aggregateTracker.Clear(); _logger.LogDebug($"Calling method: {_eventStore.GetType().Name}.{nameof(CommitAsync)}."); await _eventStore.CommitAsync().ConfigureAwait(false); _transactionStarted = false; await _eventPublisher.CommitAsync().ConfigureAwait(false); } catch (Exception e) { _logger.LogError(e.Message, e); Rollback(); throw; } }