using System.Text.Json; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Hybrid; using Microsoft.Extensions.Options; using Moonlight.Api.Configuration; using Moonlight.Api.Database; using Moonlight.Api.Database.Entities; namespace Moonlight.Api.Services; public class SettingsService { private readonly DatabaseRepository Repository; private readonly IOptions Options; private readonly HybridCache HybridCache; private const string CacheKey = "Moonlight.Api.SettingsService.{0}"; public SettingsService( DatabaseRepository repository, IOptions options, HybridCache hybridCache ) { Repository = repository; HybridCache = hybridCache; Options = options; } public async Task GetValueAsync(string key) { var cacheKey = string.Format(CacheKey, key); var value = await HybridCache.GetOrCreateAsync( cacheKey, async ct => { return await Repository .Query() .Where(x => x.Key == key) .Select(o => o.ValueJson) .FirstOrDefaultAsync(cancellationToken: ct); }, new HybridCacheEntryOptions() { LocalCacheExpiration = Options.Value.LookupL1CacheTime, Expiration = Options.Value.LookupL2CacheTime } ); if (string.IsNullOrWhiteSpace(value)) return default; return JsonSerializer.Deserialize(value); } public async Task SetValueAsync(string key, T value) { var cacheKey = string.Format(CacheKey, key); var option = await Repository .Query() .FirstOrDefaultAsync(x => x.Key == key); var json = JsonSerializer.Serialize(value); if (option != null) { option.ValueJson = json; await Repository.UpdateAsync(option); } else { option = new SettingsOption() { Key = key, ValueJson = json }; await Repository.AddAsync(option); } await HybridCache.RemoveAsync(cacheKey); } }