diff --git a/Core.Blueprint.Redis/Adapters/CacheSettings.cs b/Core.Blueprint.Redis/Adapters/CacheSettings.cs index 2be3840..128a89e 100644 --- a/Core.Blueprint.Redis/Adapters/CacheSettings.cs +++ b/Core.Blueprint.Redis/Adapters/CacheSettings.cs @@ -1,4 +1,4 @@ -namespace Core.Blueprint.Caching.Adapters +namespace Core.Blueprint.Redis { public interface ICacheSettings { diff --git a/Core.Blueprint.Redis/Configuration/RegisterBlueprint.cs b/Core.Blueprint.Redis/Configuration/RegisterBlueprint.cs index 854b173..3aeb596 100644 --- a/Core.Blueprint.Redis/Configuration/RegisterBlueprint.cs +++ b/Core.Blueprint.Redis/Configuration/RegisterBlueprint.cs @@ -1,10 +1,8 @@ -using Core.Blueprint.Caching.Adapters; -using Core.Blueprint.Caching.Contracts; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Core.Blueprint.Caching.Configuration +namespace Core.Blueprint.Redis.Configuration { /// /// Provides extension methods for registering Redis-related services in the DI container. @@ -19,30 +17,23 @@ namespace Core.Blueprint.Caching.Configuration /// The updated service collection. public static IServiceCollection AddRedis(this IServiceCollection services, IConfiguration configuration) { - // TODO for the following variable we'll need to add in the appsettings.json the following config: "UseRedisCache": true, - bool useRedis = configuration.GetValue("UseRedisCache"); - - if (useRedis) + // Retrieve the Redis connection string from the configuration. + // Get Redis configuration section + var redisConnectionString = configuration.GetSection("ConnectionStrings:Redis").Value; + if (string.IsNullOrEmpty(redisConnectionString)) { - var redisConnectionString = configuration.GetSection("ConnectionStrings:Redis").Value; - if (string.IsNullOrEmpty(redisConnectionString)) - { - throw new InvalidOperationException("Redis connection is not configured."); - } - - services.AddSingleton(provider => - new RedisCacheProvider(redisConnectionString, provider.GetRequiredService>())); - } - else - { - services.AddMemoryCache(); - services.AddSingleton(); + throw new InvalidOperationException("Redis connection is not configured."); } + // Register RedisCacheProvider + services.AddSingleton(provider => + new RedisCacheProvider(redisConnectionString, provider.GetRequiredService>())); + + // Get CacheSettings and register with the ICacheSettings interface var cacheSettings = configuration.GetSection("CacheSettings").Get(); if (cacheSettings == null) { - throw new InvalidOperationException("CacheSettings section is not configured."); + throw new InvalidOperationException("Redis CacheSettings section is not configured."); } services.AddSingleton(cacheSettings); diff --git a/Core.Blueprint.Redis/Contracts/ICacheProvider.cs b/Core.Blueprint.Redis/Contracts/IRedisCacheProvider.cs similarity index 96% rename from Core.Blueprint.Redis/Contracts/ICacheProvider.cs rename to Core.Blueprint.Redis/Contracts/IRedisCacheProvider.cs index cf0a323..f9a7b5e 100644 --- a/Core.Blueprint.Redis/Contracts/ICacheProvider.cs +++ b/Core.Blueprint.Redis/Contracts/IRedisCacheProvider.cs @@ -1,9 +1,9 @@ -namespace Core.Blueprint.Caching.Contracts +namespace Core.Blueprint.Redis { /// /// Interface for managing Redis cache operations. /// - public interface ICacheProvider + public interface IRedisCacheProvider { /// /// Retrieves a cache item by its key. diff --git a/Core.Blueprint.Redis/Core.Blueprint.Caching.csproj b/Core.Blueprint.Redis/Core.Blueprint.Caching.csproj index 8109d2c..bcfc356 100644 --- a/Core.Blueprint.Redis/Core.Blueprint.Caching.csproj +++ b/Core.Blueprint.Redis/Core.Blueprint.Caching.csproj @@ -9,7 +9,6 @@ - diff --git a/Core.Blueprint.Redis/Helpers/RedisCacheKeyHelper.cs b/Core.Blueprint.Redis/Helpers/RedisCacheKeyHelper.cs index 6d9e374..f7f53cb 100644 --- a/Core.Blueprint.Redis/Helpers/RedisCacheKeyHelper.cs +++ b/Core.Blueprint.Redis/Helpers/RedisCacheKeyHelper.cs @@ -1,7 +1,11 @@ -using System.Text; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using System.Text.RegularExpressions; +using System.Threading.Tasks; -namespace Core.Blueprint.Caching.Helpers +namespace Core.Blueprint.Redis.Helpers { /// /// Helper class for generating consistent and normalized cache keys. diff --git a/Core.Blueprint.Redis/MemoryCacheProvider.cs b/Core.Blueprint.Redis/MemoryCacheProvider.cs deleted file mode 100644 index 91beb2a..0000000 --- a/Core.Blueprint.Redis/MemoryCacheProvider.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Core.Blueprint.Caching.Contracts; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Caching.Memory; -using System.Text.Json; - -namespace Core.Blueprint.Caching -{ - public sealed class MemoryCacheProvider : ICacheProvider - { - private readonly IMemoryCache _cache; - private readonly ILogger _logger; - public MemoryCacheProvider(IMemoryCache cache, ILogger logger) - { - _cache = cache; - _logger = logger; - } - - public ValueTask GetAsync(string key) - { - if (_cache.TryGetValue(key, out var value)) - { - if (value is TEntity typedValue) - { - return ValueTask.FromResult(typedValue); - } - - try - { - var json = value?.ToString(); - var deserialized = JsonSerializer.Deserialize(json); - return ValueTask.FromResult(deserialized); - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Error deserializing cache value for key {Key}", key); - } - } - - return ValueTask.FromResult(default(TEntity)); - } - - public ValueTask SetAsync(string key, TEntity value, TimeSpan? expiry = null) - { - var options = new MemoryCacheEntryOptions(); - if (expiry.HasValue) - { - options.SetAbsoluteExpiration(expiry.Value); - } - - _cache.Set(key, value, options); - return ValueTask.CompletedTask; - } - - public ValueTask RemoveAsync(string key) - { - _cache.Remove(key); - return ValueTask.CompletedTask; - } - - public ValueTask ExistsAsync(string key) - { - return ValueTask.FromResult(_cache.TryGetValue(key, out _)); - } - - public ValueTask RefreshAsync(string key, TimeSpan? expiry = null) - { - // MemoryCache does not support sliding expiration refresh like Redis, - // so we must re-set the value manually if required. - - if (_cache.TryGetValue(key, out var value)) - { - _cache.Remove(key); - - var options = new MemoryCacheEntryOptions(); - if (expiry.HasValue) - { - options.SetAbsoluteExpiration(expiry.Value); - } - - _cache.Set(key, value, options); - } - - return ValueTask.CompletedTask; - } - } -} diff --git a/Core.Blueprint.Redis/RedisCacheProvider.cs b/Core.Blueprint.Redis/RedisCacheProvider.cs index 90901ce..525e310 100644 --- a/Core.Blueprint.Redis/RedisCacheProvider.cs +++ b/Core.Blueprint.Redis/RedisCacheProvider.cs @@ -1,15 +1,14 @@ using Azure.Identity; -using Core.Blueprint.Caching.Contracts; using Microsoft.Extensions.Logging; using StackExchange.Redis; using System.Text.Json; -namespace Core.Blueprint.Caching +namespace Core.Blueprint.Redis { /// /// Redis cache provider for managing cache operations. /// - public sealed class RedisCacheProvider : ICacheProvider + public sealed class RedisCacheProvider : IRedisCacheProvider { private IDatabase _cacheDatabase = null!; private readonly ILogger _logger; @@ -35,29 +34,14 @@ namespace Core.Blueprint.Caching /// The Redis connection string. /// An instance representing the Redis cache database. /// Thrown when the connection to Redis fails. InitializeRedisAsync(string connectionString) + async Task InitializeRedisAsync(string connectionString) { try { - var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty; - - ConfigurationOptions configurationOptions; - - if (environment.Equals("Local", StringComparison.OrdinalIgnoreCase)) - { - // Use simple local Redis config - configurationOptions = ConfigurationOptions.Parse(connectionString); - } - else - { - // Use Azure Redis config - configurationOptions = await ConfigurationOptions - .Parse(connectionString) - .ConfigureForAzureWithTokenCredentialAsync(new DefaultAzureCredential()); - } + var configurationOptions = await ConfigurationOptions.Parse($"{connectionString}") + .ConfigureForAzureWithTokenCredentialAsync(new DefaultAzureCredential()); configurationOptions.AbortOnConnectFail = false; - var connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(configurationOptions); _logger.LogInformation("Successfully connected to Redis.");