diff --git a/Kentico.Kontent.Delivery.Caching/DeliveryCacheOptions.cs b/Kentico.Kontent.Delivery.Caching/DeliveryCacheOptions.cs index 8d8d9a70..4b57f1a3 100644 --- a/Kentico.Kontent.Delivery.Caching/DeliveryCacheOptions.cs +++ b/Kentico.Kontent.Delivery.Caching/DeliveryCacheOptions.cs @@ -27,10 +27,5 @@ public class DeliveryCacheOptions /// Determines whether to use or /// public CacheTypeEnum CacheType { get; set; } = CacheTypeEnum.Memory; - - /// - /// Name of an instance the options are bound to. - /// - public string Name { get; set; } } } diff --git a/Kentico.Kontent.Delivery.Caching/Extensions/DeliveryCacheOptionsExtensions.cs b/Kentico.Kontent.Delivery.Caching/Extensions/DeliveryCacheOptionsExtensions.cs index 1d158502..5f407314 100644 --- a/Kentico.Kontent.Delivery.Caching/Extensions/DeliveryCacheOptionsExtensions.cs +++ b/Kentico.Kontent.Delivery.Caching/Extensions/DeliveryCacheOptionsExtensions.cs @@ -16,7 +16,6 @@ public static void Configure(this DeliveryCacheOptions o, DeliveryCacheOptions o o.DefaultExpiration = options.DefaultExpiration; o.DefaultExpirationType = options.DefaultExpirationType; o.StaleContentExpiration = options.StaleContentExpiration; - o.Name = options.Name; } } } diff --git a/Kentico.Kontent.Delivery.Caching/Extensions/ServiceCollectionExtensions.cs b/Kentico.Kontent.Delivery.Caching/Extensions/ServiceCollectionExtensions.cs index 7c6c004e..7c695f5d 100644 --- a/Kentico.Kontent.Delivery.Caching/Extensions/ServiceCollectionExtensions.cs +++ b/Kentico.Kontent.Delivery.Caching/Extensions/ServiceCollectionExtensions.cs @@ -30,31 +30,17 @@ public static IServiceCollection AddDeliveryClientCache(this IServiceCollection .RegisterDependencies(options.CacheType) .Decorate(); } - - /// - /// Registers cache dependencies. - /// - /// A instance for registering and resolving dependencies. - /// A - /// A name of named client which want to use cached. - /// - public static IServiceCollection RegisterDependencies(this IServiceCollection services, CacheTypeEnum cacheType, string name = null) + private static IServiceCollection RegisterDependencies(this IServiceCollection services, CacheTypeEnum cacheType) { switch (cacheType) { case CacheTypeEnum.Memory: - if (name == null) - { - services.TryAddSingleton(); - } + services.TryAddSingleton(); services.TryAddSingleton(); break; case CacheTypeEnum.Distributed: - if (name == null) - { - services.TryAddSingleton(); - } + services.TryAddSingleton(); services.TryAddSingleton(); break; } diff --git a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/DeliveryClientCacheFactoryTests.cs b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/DeliveryClientCacheFactoryTests.cs index 0b27c5a7..660046ed 100644 --- a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/DeliveryClientCacheFactoryTests.cs +++ b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/DeliveryClientCacheFactoryTests.cs @@ -1,10 +1,10 @@ -using FakeItEasy; +using Autofac; +using FakeItEasy; using FluentAssertions; using Kentico.Kontent.Delivery.Abstractions; using Kentico.Kontent.Delivery.Caching; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using System; using Xunit; namespace Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests @@ -13,7 +13,8 @@ public class DeliveryClientCacheFactoryTests { private readonly IOptionsMonitor _deliveryCacheOptionsMock; private readonly IDeliveryClientFactory _innerDeliveryClientFactoryMock; - private readonly IServiceProvider _serviceProvider; + private readonly IComponentContext _container; + private readonly IServiceCollection _serviceCollection; private const string _clientName = "ClientName"; @@ -21,7 +22,9 @@ public DeliveryClientCacheFactoryTests() { _deliveryCacheOptionsMock = A.Fake>(); _innerDeliveryClientFactoryMock = A.Fake(); - _serviceProvider = new ServiceCollection().BuildServiceProvider(); + _container = A.Fake(); + _serviceCollection = new ServiceCollection() + .AddMemoryCache(); } [Fact] @@ -31,7 +34,7 @@ public void GetNamedCacheClient_WithCorrectName_GetClient() A.CallTo(() => _deliveryCacheOptionsMock.Get(_clientName)) .Returns(deliveryCacheOptions); - var deliveryClientFactory = new DeliveryClientCacheFactory(_innerDeliveryClientFactoryMock, _deliveryCacheOptionsMock, _serviceProvider); + var deliveryClientFactory = new DeliveryClientCacheFactory(_innerDeliveryClientFactoryMock, _deliveryCacheOptionsMock, _serviceCollection.BuildServiceProvider(), _container); var result = deliveryClientFactory.Get(_clientName); @@ -45,7 +48,7 @@ public void GetNamedCacheClient_WithWrongName_GetNull() A.CallTo(() => _deliveryCacheOptionsMock.Get(_clientName)) .Returns(deliveryCacheOptions); - var deliveryClientFactory = new DeliveryClientCacheFactory(_innerDeliveryClientFactoryMock, _deliveryCacheOptionsMock, _serviceProvider); + var deliveryClientFactory = new DeliveryClientCacheFactory(_innerDeliveryClientFactoryMock, _deliveryCacheOptionsMock, _serviceCollection.BuildServiceProvider(), _container); var result = deliveryClientFactory.Get("WrongName"); diff --git a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index d40d57e2..9b9662a8 100644 --- a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -12,12 +12,14 @@ namespace Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Tests { public class ServiceCollectionExtensionsTests { - private readonly ServiceCollection _serviceCollection; + private readonly IServiceCollection _serviceCollection; private readonly IComponentContext _container; public ServiceCollectionExtensionsTests() { - _serviceCollection = new ServiceCollection(); + _serviceCollection = new ServiceCollection() + .AddMemoryCache() + .AddDistributedMemoryCache(); _container = A.Fake(); } @@ -61,6 +63,26 @@ public void AddDeliveryNamedClient_CacheWithDeliveryCacheOptions_GetNull(CacheTy client.Should().BeNull(); } + [Theory] + [InlineData(CacheTypeEnum.Memory)] + [InlineData(CacheTypeEnum.Distributed)] + public void AddDeliveryNamedClient_CacheWithDeliveryCacheOptions_GetNoNamedClientNull(CacheTypeEnum cacheType) + { + _serviceCollection.AddSingleton(_container); + _serviceCollection.AddDeliveryClient("named", new DeliveryOptions() { ProjectId = Guid.NewGuid().ToString() }); + _serviceCollection.AddDeliveryClientCache("named", new DeliveryCacheOptions() + { + CacheType = cacheType + }); + + var sp = _serviceCollection.BuildServiceProvider(); + var factory = sp.GetRequiredService(); + + var client = factory.Get(); + + client.Should().BeNull(); + } + [Fact] public void AddDeliveryNamedClient_DeliveryOptions_GetNamedClient() { @@ -87,5 +109,18 @@ public void AddDeliveryNamedClient_DeliveryOptions_GetNull() client.Should().BeNull(); } + [Fact] + public void AddDeliveryNamedClient_DeliveryOptions_GetNoNamedClientNull() + { + _serviceCollection.AddSingleton(_container); + _serviceCollection.AddDeliveryClient("named", new DeliveryOptions() { ProjectId = Guid.NewGuid().ToString() }); + var sp = _serviceCollection.BuildServiceProvider(); + + var factory = sp.GetRequiredService(); + var client = factory.Get(); + + client.Should().BeNull(); + } + } } diff --git a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/DeliveryClientCacheFactory.cs b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/DeliveryClientCacheFactory.cs index 27b0e37a..1c48b642 100644 --- a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/DeliveryClientCacheFactory.cs +++ b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/DeliveryClientCacheFactory.cs @@ -1,4 +1,6 @@ -using Kentico.Kontent.Delivery.Abstractions; +using Autofac; +using Autofac.Core.Registration; +using Kentico.Kontent.Delivery.Abstractions; using Kentico.Kontent.Delivery.Caching; using Kentico.Kontent.Delivery.Caching.Factories; using Microsoft.Extensions.Caching.Distributed; @@ -14,6 +16,7 @@ internal class DeliveryClientCacheFactory : IDeliveryClientFactory { private readonly IOptionsMonitor _deliveryCacheOptions; private readonly IServiceProvider _serviceProvider; + private readonly IComponentContext _componentContext; private readonly IDeliveryClientFactory _innerDeliveryClientFactory; private readonly ConcurrentDictionary _cache = new ConcurrentDictionary(); @@ -23,10 +26,12 @@ internal class DeliveryClientCacheFactory : IDeliveryClientFactory /// Factory to be decorated. /// Cache configuration options. /// An instance. - public DeliveryClientCacheFactory(IDeliveryClientFactory deliveryClientFactory, IOptionsMonitor deliveryCacheOptions, IServiceProvider serviceProvider) + /// An autofac container + public DeliveryClientCacheFactory(IDeliveryClientFactory deliveryClientFactory, IOptionsMonitor deliveryCacheOptions, IServiceProvider serviceProvider, IComponentContext componentContext) { _deliveryCacheOptions = deliveryCacheOptions; _serviceProvider = serviceProvider; + _componentContext = componentContext; _innerDeliveryClientFactory = deliveryClientFactory; } @@ -40,26 +45,29 @@ public IDeliveryClient Get(string name) if (!_cache.TryGetValue(name, out var client)) { client = _innerDeliveryClientFactory.Get(name); - var cacheOptions = _deliveryCacheOptions.Get(name); - if (cacheOptions.Name == name) + if (client != null) { - // Build caching services according to the options - IDeliveryCacheManager manager; - if (cacheOptions.CacheType == CacheTypeEnum.Memory) + var cacheOptions = _deliveryCacheOptions.Get(name); + if (cacheOptions != null) { - var memoryCache = _serviceProvider.GetService(); - manager = CacheManagerFactory.Create(memoryCache, Options.Create(cacheOptions)); - } - else - { - var distributedCache = _serviceProvider.GetService(); - manager = CacheManagerFactory.Create(distributedCache, Options.Create(cacheOptions)); - } + // Build caching services according to the options + IDeliveryCacheManager manager; + if (cacheOptions.CacheType == CacheTypeEnum.Memory) + { + var memoryCache = GetNamedServiceOrDefault(name); + manager = CacheManagerFactory.Create(memoryCache, Options.Create(cacheOptions)); + } + else + { + var distributedCache = GetNamedServiceOrDefault(name); + manager = CacheManagerFactory.Create(distributedCache, Options.Create(cacheOptions)); + } - // Decorate the client with a caching layer - client = new DeliveryClientCache(manager, client); + // Decorate the client with a caching layer + client = new DeliveryClientCache(manager, client); - _cache.TryAdd(name, client); + _cache.TryAdd(name, client); + } } } @@ -67,5 +75,17 @@ public IDeliveryClient Get(string name) } public IDeliveryClient Get() => _innerDeliveryClientFactory.Get(); + + private T GetNamedServiceOrDefault(string name) + { + try + { + return _componentContext.ResolveNamed(name); + } + catch (ComponentNotRegisteredException) + { + return _serviceProvider.GetService(); + } + } } } diff --git a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/Extensions/ServiceCollectionExtensions.cs b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/Extensions/ServiceCollectionExtensions.cs index a3da13cb..959be2d1 100644 --- a/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/Extensions/ServiceCollectionExtensions.cs +++ b/Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection/Extensions/ServiceCollectionExtensions.cs @@ -3,8 +3,11 @@ using Kentico.Kontent.Delivery.Caching.Extensions; using Kentico.Kontent.Delivery.Configuration; using Kentico.Kontent.Delivery.Helpers; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using System; namespace Kentico.Kontent.Delivery.Extensions.Autofac.DependencyInjection.Extensions @@ -104,5 +107,21 @@ private static IServiceCollection RegisterOptions(this IServiceCollection servic { return services.Configure(name, (o) => o.Configure(options)); } + + private static IServiceCollection RegisterDependencies(this IServiceCollection services, CacheTypeEnum cacheType, string name) + { + switch (cacheType) + { + case CacheTypeEnum.Memory: + services.TryAddSingleton(); + break; + + case CacheTypeEnum.Distributed: + services.TryAddSingleton(); + break; + } + + return services; + } } }