public async Task InsertOrUpdateSnapshot_Tests()
        {
            //Arrange
            var product = new Product
                          (
                1L,
                "banana",
                true,
                new List <long>()
            {
                1L,
                2L,
                3L
            },
                new List <ProductRecord>()
            {
                new ProductRecord(1L, "a", DateTime.UtcNow),
                new ProductRecord(2L, "b", DateTime.UtcNow),
                new ProductRecord(3L, "c", DateTime.UtcNow),
                new ProductRecord(4L, "d", DateTime.UtcNow),
            }
                          );

            //Act
            await _savableAggregateSnapshotter.SaveSnapshotAsync(product, typeof(Product), (product as IAggregateRoot).Version);
        }
        public async Task <AsyncTaskResult> UpdatePublishedVersionAsync(string processorName, string aggregateRootTypeName, string aggregateRootId, int publishedVersion)
        {
            if (publishedVersion == 1)
            {
                var record = new PublishedVersion()
                {
                    ProcessorName         = processorName,
                    AggregateRootTypeName = aggregateRootTypeName,
                    AggregateRootId       = aggregateRootId,
                    Version   = 1,
                    CreatedOn = DateTime.UtcNow
                };
                try
                {
                    await _publishedVersionCollection.GetCollection(aggregateRootId).InsertOneAsync(record);

                    return(AsyncTaskResult.Success);
                }
                catch (MongoWriteException ex)
                {
                    if (ex.WriteError.Code == 11000 && ex.Message.Contains(nameof(record.ProcessorName)) && ex.Message.Contains(nameof(record.AggregateRootId)) && ex.Message.Contains(nameof(record.Version)))
                    {
                        return(AsyncTaskResult.Success);
                    }
                    _logger.Error("Insert aggregate published version has write exception.", ex);
                    return(new AsyncTaskResult(AsyncTaskStatus.IOException, ex.Message));
                }
                catch (Exception ex)
                {
                    _logger.Error("Insert aggregate published version has unknown exception.", ex);
                    return(new AsyncTaskResult(AsyncTaskStatus.Failed, ex.Message));
                }
            }
            else
            {
                try
                {
                    var builder = Builders <PublishedVersion> .Filter;
                    var filter  = builder.Eq(e => e.ProcessorName, processorName)
                                  & builder.Eq(e => e.AggregateRootId, aggregateRootId)
                                  & builder.Eq(e => e.Version, publishedVersion - 1);
                    var update = Builders <PublishedVersion> .Update
                                 .Set(e => e.Version, publishedVersion)
                                 .Set(e => e.CreatedOn, DateTime.UtcNow);

                    await _publishedVersionCollection.GetCollection(aggregateRootId)
                    .UpdateOneAsync(filter, update);

                    await _savableAggregateSnapshotter.SaveSnapshotAsync(aggregateRootId, _typeNameProvider.GetType(aggregateRootTypeName), publishedVersion);

                    return(AsyncTaskResult.Success);
                }
                catch (MongoException ex)
                {
                    _logger.Error("Update aggregate published version has update exception.", ex);
                    return(new AsyncTaskResult(AsyncTaskStatus.IOException, ex.Message));
                }
                catch (Exception ex)
                {
                    _logger.Error("Update aggregate published version has unknown exception.", ex);
                    return(new AsyncTaskResult(AsyncTaskStatus.Failed, ex.Message));
                }
            }
        }