using LiveForum.Code.Redis.Contract; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace LiveForum.Code.SystemCache { /// /// 系统缓存服务基类(用于底层支持需要的系统级缓存) /// /// 缓存值类型 /// 键类型(用于从缓存值中提取键) public abstract class SystemCacheServiceBase : ISystemCacheService where TKey : notnull { protected readonly IRedisService _redisService; protected abstract string CacheKey { get; } protected abstract TimeSpan CacheExpiration { get; } protected SystemCacheServiceBase(IRedisService redisService) { _redisService = redisService; } /// /// 从缓存值中提取键(子类需要实现) /// /// 缓存值 /// protected abstract TKey GetKeyFromValue(TValue value); /// /// 从数据库加载所有数据(子类需要实现) /// /// 数据列表 protected abstract Task> LoadFromDatabaseAsync(); /// /// 获取所有缓存数据(从缓存或数据库加载) /// public virtual async Task> GetAllAsync() { try { // 先从缓存获取 var cachedData = await _redisService.GetAsync>(CacheKey); if (cachedData != null && cachedData.Any()) { return cachedData; } // 缓存未命中,从数据库加载 var data = await LoadFromDatabaseAsync(); if (data != null && data.Any()) { // 写入缓存 await _redisService.SetAsync(CacheKey, data, CacheExpiration); } return data ?? new List(); } catch (Exception ex) { // 记录错误但不抛出异常,尝试从数据库加载 // 可以在这里添加日志记录 return await LoadFromDatabaseAsync() ?? new List(); } } /// /// 根据键获取缓存数据 /// public virtual async Task GetByKeyAsync(object key) { if (key == null) { return default(TValue); } var allData = await GetAllAsync(); TKey keyValue; if (key is TKey directKey) { keyValue = directKey; } else { try { keyValue = (TKey)Convert.ChangeType(key, typeof(TKey)); } catch { return default(TValue); } } return allData.FirstOrDefault(x => GetKeyFromValue(x).Equals(keyValue)); } /// /// 清除缓存 /// public virtual async Task ClearCacheAsync() { try { await _redisService.RemoveAsync(CacheKey); } catch { // 忽略缓存清除错误 } } /// /// 刷新缓存(清除并重新加载) /// public virtual async Task RefreshCacheAsync() { await ClearCacheAsync(); await GetAllAsync(); } } }