using System.Text.Json; using HealthManager.Domain.Entities; using HealthManager.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace HealthManager.Application.Services; public class CacheService(AppDbContext db) { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true }; public async Task GetAsync(string key) where T : class { var entry = await db.CacheEntries .FirstOrDefaultAsync(c => c.Key == key && c.ExpiresAt > DateTime.UtcNow); if (entry == null) return default; return JsonSerializer.Deserialize(entry.Value.RootElement.GetRawText(), JsonOptions); } public async Task SetAsync(string key, T value, TimeSpan ttl) { var json = JsonSerializer.SerializeToDocument(value); var existing = await db.CacheEntries.FirstOrDefaultAsync(c => c.Key == key); if (existing != null) { existing.Value = json; existing.ExpiresAt = DateTime.UtcNow.Add(ttl); } else { db.CacheEntries.Add(new CacheEntry { Key = key, Value = json, ExpiresAt = DateTime.UtcNow.Add(ttl), }); } await db.SaveChangesAsync(); } public async Task GetOrSetAsync(string key, Func> factory, TimeSpan ttl) where T : class { var cached = await GetAsync(key); if (cached != null) return cached; var value = await factory(); await SetAsync(key, value, ttl); return value; } public async Task RemoveAsync(string key) { await db.CacheEntries.Where(c => c.Key == key).ExecuteDeleteAsync(); } }