public static IUnleashServiceCollection WithDistributedToggleCollectionCache(
            this IUnleashServiceCollection serviceCollection,
            Action <DistributedToggleCollectionCacheSettings> settingsConfigurator = null)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

            var settings = new DistributedToggleCollectionCacheSettings();

            if (serviceCollection.UnleashConfiguration != null)
            {
                var section = serviceCollection.UnleashConfiguration.GetSection("Caching:Distributed");
                section.Bind(settings);
            }

            settingsConfigurator?.Invoke(settings);

            SettingsValidator.Validate(settings);

            serviceCollection.AddSingleton(settings);

            serviceCollection.WithToggleCollectionCache <DistributedToggleCollectionCache>();

            return(serviceCollection);
        }
        public async Task Load_WhenTogglesOrEtagFileDoesNotExists_ReturnsEmptyResult(
            bool toggleCollectionExists,
            bool etagExists,
            [Frozen] DistributedToggleCollectionCacheSettings settings,
            [Frozen] MemoryDistributedCache distributedCache,
            DistributedToggleCollectionCache cache
            )
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            settings.EtagKeyName             = "Etag";
            settings.ToggleCollectionKeyName = "Toggles";

            if (toggleCollectionExists)
            {
                var toggleCollection = new ToggleCollection();

                using (var ms = new MemoryStream())
                {
                    jsonSerializer.Serialize(ms, toggleCollection);
                    ms.Seek(0, SeekOrigin.Begin);

                    await distributedCache.SetAsync(settings.ToggleCollectionKeyName, ms.ToArray(), settings.ToggleCollectionEntryOptions, CancellationToken.None).ConfigureAwait(false);
                }
            }

            if (toggleCollectionExists && etagExists)
            {
                var etag = Guid.NewGuid().ToString();
                distributedCache.SetString(settings.EtagKeyName, etag);
            }

            var result = await cache.Load(CancellationToken.None);

            Assert.Equal(string.Empty, result.InitialETag);
            Assert.Null(result.InitialToggleCollection);
        }
        public async Task Load_WhenValidToggleAndEtagFilesExist_ReturnsExpectedResult(
            [Frozen] MemoryDistributedCache distributedCache,
            ToggleCollection toggleCollection,
            string etag
            )
        {
            var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings();
            var jsonSerializer         = new NewtonsoftJsonSerializer(jsonSerializerSettings);

            var settings = new DistributedToggleCollectionCacheSettings
            {
                EtagEntryOptions =
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
                },
                ToggleCollectionEntryOptions =
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
                }
            };

            using (var ms = new MemoryStream())
            {
                jsonSerializer.Serialize(ms, toggleCollection);
                ms.Seek(0, SeekOrigin.Begin);

                await distributedCache.SetAsync(settings.ToggleCollectionKeyName, ms.ToArray(), settings.ToggleCollectionEntryOptions, CancellationToken.None).ConfigureAwait(false);

                await distributedCache.SetStringAsync(settings.EtagKeyName, etag, settings.EtagEntryOptions, CancellationToken.None).ConfigureAwait(false);
            }

            var cache  = new DistributedToggleCollectionCache(settings, distributedCache, jsonSerializer);
            var result = await cache.Load(CancellationToken.None);

            Assert.Equal(etag, result.InitialETag);

            AssertionUtils.AssertToggleCollectionsEquivalent(toggleCollection, result.InitialToggleCollection);
        }