Esempio n. 1
0
        /// <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;
            }
        }