using MesETL.App.Options; using Microsoft.Extensions.DependencyInjection; using StackExchange.Redis; namespace MesETL.App.Cache; public class RedisCache : ICacher { private readonly IDatabase _db; public string KeyPrefix { get; set; } public RedisCache(IConnectionMultiplexer conn, int dataBase, string keyPrefix = "") { _db = conn.GetDatabase(dataBase); KeyPrefix = keyPrefix; } public async Task GetStringAsync(string key) { var value = await _db.StringGetAsync($"{KeyPrefix}{key}"); return !value.HasValue ? null : value.ToString(); } public async Task SetStringAsync(string key, string value) { if (!await _db.StringSetAsync($"{KeyPrefix}{key}", value)) throw new RedisCommandException("设置Redis缓存失败"); } public Task ExistsAsync(string key) { return _db.KeyExistsAsync($"{KeyPrefix}{key}"); } public Task SetHashAsync(string key, IReadOnlyDictionary hash) { return _db.HashSetAsync($"{KeyPrefix}{key}", hash.Select(pair => new HashEntry(pair.Key, pair.Value)).ToArray()); } public async Task> GetHashAsync(string key) { var entries = await _db.HashGetAllAsync($"{KeyPrefix}{key}"); var result = new Dictionary(); foreach (var entry in entries) { result.Add(entry.Name.ToString(), entry.Value.ToString()); } return result; } } public static class RedisCacheExtensions { public static IServiceCollection AddRedisCache(this IServiceCollection services, RedisCacheOptions options) { var conn = ConnectionMultiplexer.Connect(options.Configuration ?? throw new ApplicationException("未配置Redis连接字符串")); services.AddSingleton(new RedisCache(conn, options.Database, options.InstanceName)); return services; } }