コード例 #1
0
        private async Task CommitChanges(AggregateRoot <TAggregateKey, TEventKey> aggregate)
        {
            var expectedVersion = aggregate.LastCommittedVersion;

            var item = await _eventStorageProvider.GetLastEventAsync(aggregate.Id);

            if ((item != null) && (expectedVersion == (int)StreamState.NoStream))
            {
                throw new AggregateCreationException($"Aggregate {item.CorrelationId} can't be created as it already exists with version {item.TargetVersion + 1}");
            }
            else if ((item != null) && ((item.TargetVersion + 1) != expectedVersion))
            {
                throw new ConcurrencyException($"Aggregate {item.CorrelationId} has been modified externally and has an updated state. Can't commit changes.");
            }

            var changesToCommit = aggregate
                                  .GetUncommittedChanges()
                                  .Select(e => (IEvent <TEventKey, TAggregate, TAggregateKey>)e)
                                  .ToList();

            //perform pre commit actions
            foreach (var e in changesToCommit)
            {
                DoPreCommitTasks(e);
            }

            //CommitAsync events to storage provider
            await _eventStorageProvider.SaveAsync(aggregate);

            //Publish to event publisher asynchronously
            foreach (var e in changesToCommit)
            {
                if (_eventPublisher != null)
                {
                    await _eventPublisher.PublishAsync(e);
                }
            }

            //If the Aggregate implements snapshottable

            if ((aggregate is ISnapshottable <TSnapshotKey, TAggregateKey, TSnapshot> snapshottable) && (_snapshotStorageProvider != null))
            {
                //Every N events we save a snapshot
                if ((aggregate.CurrentVersion >= _snapshotStorageProvider.SnapshotFrequency) &&
                    (
                        (changesToCommit.Count >= _snapshotStorageProvider.SnapshotFrequency) ||
                        (aggregate.CurrentVersion % _snapshotStorageProvider.SnapshotFrequency < changesToCommit.Count) ||
                        (aggregate.CurrentVersion % _snapshotStorageProvider.SnapshotFrequency == 0)
                    )
                    )
                {
                    var snapshot = snapshottable.TakeSnapshot();
                    await _snapshotStorageProvider.SaveSnapshotAsync(snapshot);
                }
            }

            aggregate.MarkChangesAsCommitted();
        }
コード例 #2
0
        private async Task CommitChangesAsync(Aggregate aggregate)
        {
            var expectedVersion = aggregate.LastCommittedVersion;

            var item = await _eventStorageProvider.GetLastEventAsync(aggregate.GetType(), aggregate.Id)
                       .ConfigureAwait(false);

            if (item != null && expectedVersion == (int)Aggregate.StreamState.NoStream)
            {
                throw new AggregateCreationException(aggregate.Id, item.TargetVersion + 1);
            }
            if (item != null && item.TargetVersion + 1 != expectedVersion)
            {
                throw new ConcurrencyException(aggregate.Id);
            }

            var changesToCommit = aggregate.GetUncommittedChanges().ToList();

            Logger.Debug("Performing pre commit checks");

            //perform pre commit actions
            foreach (var e in changesToCommit)
            {
                DoPreCommitTasks(e);
            }

            //CommitAsync events to storage provider
            await _eventStorageProvider.CommitChangesAsync(aggregate)
            .ConfigureAwait(false);

            //Publish to event publisher asynchronously
            if (_eventPublisher != null)
            {
                foreach (var e in changesToCommit)
                {
                    await _eventPublisher.PublishAsync(e)
                    .ConfigureAwait(false);
                }
            }

            //If the Aggregate implements snapshottable
            var snapshottable = aggregate as ISnapshottable;

            if (snapshottable != null && _snapshotStorageProvider != null)
            {
                //Every N events we save a snapshot
                if (ShouldCreateSnapShot(aggregate, changesToCommit))
                {
                    await _snapshotStorageProvider.SaveSnapshotAsync(aggregate.GetType(), snapshottable.TakeSnapshot())
                    .ConfigureAwait(false);
                }
            }

            aggregate.MarkChangesAsCommitted();
        }
コード例 #3
0
        public async Task GetLastEventAsync_should_return_last_event()
        {
            var aggregateId = Guid.NewGuid();

            var aggregate = new BankAccount(aggregateId, "Account Name");

            await CommitChangesAsync(aggregate)
            .ConfigureAwait(false);

            var actual = await _provider.GetLastEventAsync(aggregate.GetType(), aggregateId)
                         .ConfigureAwait(false);

            actual.AggregateId.Should().Be(aggregateId);
            actual.TargetVersion.Should().Be(-1);
            actual.Should().BeOfType <AccountCreatedEvent>();
        }
コード例 #4
0
ファイル: Repository.cs プロジェクト: hixio-mh/NEventLite
        private async Task CommitChanges(TAggregate aggregate)
        {
            var expectedVersion = aggregate.LastCommittedVersion;

            var item = await _eventStorageProvider.GetLastEventAsync <TAggregate, TAggregateKey>(aggregate.Id);

            if ((item != null))
            {
                if (expectedVersion == (long)StreamState.NoStream)
                {
                    throw new AggregateCreationException($"Aggregate {item.CorrelationId} can't be created as it already exists with version {item.TargetVersion + 1}");
                }

                if ((item.TargetVersion + 1) != expectedVersion)
                {
                    throw new ConcurrencyException($"Aggregate {item.CorrelationId} has been modified externally and has an updated state. Can't commit changes.");
                }
            }

            var changesToCommit = aggregate
                                  .GetUncommittedChanges()
                                  .Cast <IEvent <TAggregate, TAggregateKey, TEventKey> >()
                                  .ToList();

            //perform pre commit actions
            DoPreCommitTasks(changesToCommit);

            //CommitAsync events to storage provider
            await _eventStorageProvider.SaveAsync <TAggregate, TAggregateKey>(aggregate.Id, changesToCommit);

            //Publish to event publisher asynchronously
            await PublishEventsAsync(changesToCommit);

            //If the Aggregate implements snapshottable
            await SaveSnapshotAsync(aggregate, changesToCommit);

            //Finally mark them committed
            aggregate.MarkChangesAsCommitted();
        }
コード例 #5
0
 public Task <IEvent> GetLastEventAsync(Type aggregateType, Guid aggregateId)
 {
     return(LogMethodCallAsync(() => _decorated.GetLastEventAsync(aggregateType, aggregateId), new object[] { aggregateType, aggregateId }));
 }