Ejemplo n.º 1
0
        public async Task <int> Save(IAggregate aggregate, bool concurrencyCheck = true)
        {
            var streamName = StreamName($"{aggregate.GetType().Name }-{aggregate.Id}");

            var pendingEvents   = aggregate.GetPendingEvents();
            var originalVersion = concurrencyCheck ? aggregate.Version - pendingEvents.Count : ExpectedVersion.Any;

            WriteResult result;

            var commitHeaders = CreateCommitHeaders(aggregate);
            var eventsToSave  = pendingEvents.Select(x => ToEventData(Guid.NewGuid(), x, commitHeaders));

            var eventBatches = GetEventBatches(eventsToSave);

            if (eventBatches.Count == 1)
            {
                // If just one batch write them straight to the Event Store
                result = await _eventStoreConnection.AppendToStreamAsync(streamName, originalVersion, eventBatches[0]);
            }
            else
            {
                // If we have more events to save than can be done in one batch according to the WritePageSize, then we need to save them in a transaction to ensure atomicity
                using (var transaction = await _eventStoreConnection.StartTransactionAsync(streamName, originalVersion))
                {
                    foreach (var batch in eventBatches)
                    {
                        await transaction.WriteAsync(batch);
                    }

                    result = await transaction.CommitAsync();
                }
            }

            aggregate.ClearPendingEvents();
            return((int)result.NextExpectedVersion);
        }