Пример #1
0
        public async Task SaveAsync(TAggregateRoot aggregate, CancellationToken cancellationToken = default)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            var events   = aggregate.GetUncommittedChanges().ToList();
            var streamId = aggregate.GetStream();
            var aggregateLoadedAtVersion = aggregate.Version;

            aggregate.MarkChangesAsCommitted();

            await _eventStore.AppendEventsToStreamAsync(streamId, events, aggregateLoadedAtVersion, cancellationToken);

            if (aggregate is ISnapshotableEntity snapshotableAggregate)
            {
                var snapshotVersionFrequency =
                    snapshotableAggregate.SnapshotVersionFrequency ??
                    _eventSourcingOptions?.DefaultSnapshotVersionFrequency ??
                    new EventSourcingOptions().DefaultSnapshotVersionFrequency;

                if (aggregate.Version - snapshotableAggregate.SnapshotVersion >= snapshotVersionFrequency)
                {
                    var(snapshot, snapshotVersion) = snapshotableAggregate.TakeSnapshot();
                    await _snapshotStore.StoreSnapshotAsync(new SnapshotEnvelope(snapshot, snapshotVersion, streamId), cancellationToken);
                }
            }

            await PublishEventsAsync(events, cancellationToken);

            stopWatch.Stop();
            _logger.LogDebug("EventSourcedRepository.SaveAsync for {AggregateType} took {ElapsedMilliseconds} ms.", typeof(TAggregateRoot).Name, stopWatch.ElapsedMilliseconds);
        }
        /// <summary>
        /// Commits the asynchronous.
        /// </summary>
        /// <param name="eventStore">The event store.</param>
        /// <param name="snapshotStore">The snapshot store.</param>
        /// <param name="sourceId">The source identifier.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public override async Task <IReadOnlyCollection <IDomainEvent> > CommitAsync(IEventStore eventStore, ISnapshotStore snapshotStore, ISourceId sourceId, CancellationToken cancellationToken)
        {
            var domainEvents = await CommitDomainEventAsync(eventStore, sourceId, cancellationToken);

            if (!await SnapshotStrategy.ShouldCreateSnapshotAsync(this, cancellationToken))
            {
                return(domainEvents);
            }


            var snapshotContainer = await CreateSnapshotContainerAsync(cancellationToken);

            await snapshotStore.StoreSnapshotAsync <TAggregate, TIdentity, TSnapshot>(
                Id,
                snapshotContainer,
                cancellationToken)
            ;

            return(domainEvents);
        }