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); }