using Application.Abstractions.Cache; using StackExchange.Redis; using System.Text.Json; namespace Infrastructure.Cache; public sealed class RedisCacheService(IConnectionMultiplexer redis) : ICacheService { private readonly IDatabase _db = redis.GetDatabase(); private static readonly JsonSerializerOptions _jsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = false }; public async Task GetAsync(string key, CancellationToken ct = default) { var value = await _db.StringGetAsync(key); if (value.IsNullOrEmpty) { return default; } return JsonSerializer.Deserialize((string)value!, _jsonOptions); } public async Task SetAsync(string key, T value, CancellationToken ct = default) { await _db.StringSetAsync(key, JsonSerializer.Serialize(value, _jsonOptions)); } public async Task SetAsync(string key, T value, TimeSpan expiry, CancellationToken ct = default) { await _db.StringSetAsync(key, JsonSerializer.Serialize(value, _jsonOptions), expiry); } public async Task RemoveAsync(string key, CancellationToken ct = default) { await _db.KeyDeleteAsync(key); } public async Task RemoveByPrefixAsync(string prefix, CancellationToken ct = default) { var server = redis.GetServer(_db.Multiplexer.GetEndPoints().First()); var keys = server.Keys(pattern: $"{prefix}*").ToArray(); if (keys.Length > 0) { await _db.KeyDeleteAsync(keys); } } }