public async Task SaveAndRestoreSnapshot_Tests()
        {
            //Arrange
            var product = new Product
                          (
                1L,
                "tomato",
                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 _aggregateSnapshotSaver.SaveAsync(product, typeof(Product), (product as IAggregateRoot).Version);

            await Task.Delay(1500);

            var restoredProduct = (await _aggregateSnapshotter.RestoreFromSnapshotAsync(typeof(Product), product.Id.ToString())) as Product;

            //Assert
            restoredProduct.Id.ShouldBe(product.Id);
            restoredProduct.Name.ShouldBe(product.Name);
            restoredProduct.IsPublished.ShouldBe(product.IsPublished);
        }
        public async Task 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);
                }
                catch (MongoWriteException ex)
                {
                    if (ex.WriteError.Code == 11000 && ex.Message.Contains(nameof(PublishedVersion.ProcessorName)) && ex.Message.Contains(nameof(PublishedVersion.AggregateRootId)) && ex.Message.Contains(nameof(PublishedVersion.Version)))
                    {
                        return;
                    }
                    var errorMessage = string.Format("Insert aggregate published version has mongo exception, aggregateRootType: {0}, aggregateRootId: {1}", aggregateRootTypeName, aggregateRootId);
                    _logger.Error(errorMessage, ex);
                    throw;
                }
                catch (Exception ex)
                {
                    var errorMessage = string.Format("Insert aggregate published version has unknown exception, aggregateRootType: {0}, aggregateRootId: {1}", aggregateRootTypeName, aggregateRootId);
                    _logger.Error(errorMessage, ex);
                    throw;
                }
            }
            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 _aggregateSnapshotSaver.SaveAsync(aggregateRootId, _typeNameProvider.GetType(aggregateRootTypeName), publishedVersion);
                }
                catch (MongoException ex)
                {
                    var errorMessage = string.Format("Update aggregate published version has mongo exception, aggregateRootType: {0}, aggregateRootId: {1}", aggregateRootTypeName, aggregateRootId);
                    _logger.Error(errorMessage, ex);
                    throw;
                }
                catch (Exception ex)
                {
                    var errorMessage = string.Format("Update aggregate published version has unknown exception, aggregateRootType: {0}, aggregateRootId: {1}", aggregateRootTypeName, aggregateRootId);
                    _logger.Error(errorMessage, ex);
                    throw;
                }
            }
        }