Asp.Net Core基于StackExchange Redis 缓存

NuGet安装

StackExchange.Redis

Microsoft.Extensions.Options

0. appsettings.json初始化配置

javascript 复制代码
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Redis": {
    "ConnectionString": "localhost:6379",
    "InstanceName": "anna_",
    "DefaultDatabase": 5,
    "ConnectRetry": 3,
    "ConnectTimeout": 5000,
    "AbortOnConnectFail": false
  },
  "ConnectionStrings": {
    "default": "Host=10.10.11.185;Port=5432;Database=KSJGOM2DB;Username=postgres;Password=money13;"
  }
}

1.Redis初始化对象

cs 复制代码
/// <summary>
/// Redis初始化对象
/// </summary>
public class RedisOptions
{
    public const string Redis = "Redis";

    public string ConnectionString { get; set; }
    public string InstanceName { get; set; }
    public int DefaultDatabase { get; set; } = 0;
    public int ConnectRetry { get; set; } = 3;
    public int ConnectTimeout { get; set; } = 5000;
    public bool AbortOnConnectFail { get; set; } = false;
}

2.接口

cs 复制代码
public interface IRedisService
{
    #region String 操作
    Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null);
    Task<T> StringGetAsync<T>(string key);
    Task<long> StringIncrementAsync(string key, long value = 1);
    Task<long> StringDecrementAsync(string key, long value = 1);
    #endregion

    #region Hash 操作
    Task<bool> HashSetAsync<T>(string hashKey, string key, T value);
    Task<bool> HashDeleteAsync(string hashKey, string key);
    Task<T> HashGetAsync<T>(string hashKey, string key);
    Task<Dictionary<string, T>> HashGetAllAsync<T>(string hashKey);
    Task<long> HashLengthAsync(string hashKey);
    #endregion

    #region List 操作
    Task<long> ListLeftPushAsync<T>(string key, T value);
    Task<long> ListRightPushAsync<T>(string key, T value);
    Task<T> ListLeftPopAsync<T>(string key);
    Task<T> ListRightPopAsync<T>(string key);
    Task<long> ListLengthAsync(string key);
    Task<IEnumerable<T>> ListRangeAsync<T>(string key, long start = 0, long stop = -1);
    #endregion

    #region Set 操作
    Task<bool> SetAddAsync<T>(string key, T value);
    Task<bool> SetRemoveAsync<T>(string key, T value);
    Task<bool> SetContainsAsync<T>(string key, T value);
    Task<long> SetLengthAsync(string key);
    Task<IEnumerable<T>> SetMembersAsync<T>(string key);
    #endregion

    #region SortedSet 操作
    Task<bool> SortedSetAddAsync<T>(string key, T value, double score);
    Task<bool> SortedSetRemoveAsync<T>(string key, T value);
    Task<double?> SortedSetScoreAsync<T>(string key, T value);
    Task<long> SortedSetLengthAsync(string key);
    Task<IEnumerable<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending);
    Task<IEnumerable<T>> SortedSetRangeByScoreAsync<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending);
    #endregion

    #region 通用操作
    Task<bool> KeyDeleteAsync(string key);
    Task<bool> KeyExistsAsync(string key);
    Task<bool> KeyExpireAsync(string key, TimeSpan? expiry);
    Task<TimeSpan?> KeyTimeToLiveAsync(string key);
    #endregion
}

3. 实现

cs 复制代码
public class RedisService : IRedisService, IDisposable
{
    private readonly IConnectionMultiplexer _redis;
    private readonly RedisOptions _options;
    private readonly IDatabase _database;
    private readonly JsonSerializerOptions _jsonOptions;

    public RedisService(IOptions<RedisOptions> optionsAccessor)
    {
        _options = optionsAccessor.Value;
        _jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = false
        };

        var config = ConfigurationOptions.Parse(_options.ConnectionString);
        config.AbortOnConnectFail = _options.AbortOnConnectFail;
        config.ConnectRetry = _options.ConnectRetry;
        config.ConnectTimeout = _options.ConnectTimeout;

        _redis = ConnectionMultiplexer.Connect(config);
        _database = _redis.GetDatabase(_options.DefaultDatabase);
    }

    private string GetPrefixedKey(string key) => $"{_options.InstanceName}{key}";

    #region String 操作实现
    public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.StringSetAsync(GetPrefixedKey(key), json, expiry);
    }

    public async Task<T> StringGetAsync<T>(string key)
    {
        var value = await _database.StringGetAsync(GetPrefixedKey(key));
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<long> StringIncrementAsync(string key, long value = 1)
    {
        return await _database.StringIncrementAsync(GetPrefixedKey(key), value);
    }

    public async Task<long> StringDecrementAsync(string key, long value = 1)
    {
        return await _database.StringDecrementAsync(GetPrefixedKey(key), value);
    }
    #endregion

    #region Hash 操作实现
    public async Task<bool> HashSetAsync<T>(string hashKey, string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.HashSetAsync(GetPrefixedKey(hashKey), key, json);
    }

    public async Task<bool> HashDeleteAsync(string hashKey, string key)
    {
        return await _database.HashDeleteAsync(GetPrefixedKey(hashKey), key);
    }

    public async Task<T> HashGetAsync<T>(string hashKey, string key)
    {
        var value = await _database.HashGetAsync(GetPrefixedKey(hashKey), key);
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<Dictionary<string, T>> HashGetAllAsync<T>(string hashKey)
    {
        var entries = await _database.HashGetAllAsync(GetPrefixedKey(hashKey));
        return entries.ToDictionary(
            x => x.Name.ToString(),
            x => JsonSerializer.Deserialize<T>(x.Value, _jsonOptions));
    }

    public async Task<long> HashLengthAsync(string hashKey)
    {
        return await _database.HashLengthAsync(GetPrefixedKey(hashKey));
    }
    #endregion

    #region List 操作实现
    public async Task<long> ListLeftPushAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.ListLeftPushAsync(GetPrefixedKey(key), json);
    }

    public async Task<long> ListRightPushAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.ListRightPushAsync(GetPrefixedKey(key), json);
    }

    public async Task<T> ListLeftPopAsync<T>(string key)
    {
        var value = await _database.ListLeftPopAsync(GetPrefixedKey(key));
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<T> ListRightPopAsync<T>(string key)
    {
        var value = await _database.ListRightPopAsync(GetPrefixedKey(key));
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<long> ListLengthAsync(string key)
    {
        return await _database.ListLengthAsync(GetPrefixedKey(key));
    }

    public async Task<IEnumerable<T>> ListRangeAsync<T>(string key, long start = 0, long stop = -1)
    {
        var values = await _database.ListRangeAsync(GetPrefixedKey(key), start, stop);
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }
    #endregion

    #region Set 操作实现
    public async Task<bool> SetAddAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SetAddAsync(GetPrefixedKey(key), json);
    }

    public async Task<bool> SetRemoveAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SetRemoveAsync(GetPrefixedKey(key), json);
    }

    public async Task<bool> SetContainsAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SetContainsAsync(GetPrefixedKey(key), json);
    }

    public async Task<long> SetLengthAsync(string key)
    {
        return await _database.SetLengthAsync(GetPrefixedKey(key));
    }

    public async Task<IEnumerable<T>> SetMembersAsync<T>(string key)
    {
        var values = await _database.SetMembersAsync(GetPrefixedKey(key));
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }
    #endregion

    #region SortedSet 操作实现
    public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SortedSetAddAsync(GetPrefixedKey(key), json, score);
    }

    public async Task<bool> SortedSetRemoveAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SortedSetRemoveAsync(GetPrefixedKey(key), json);
    }

    public async Task<double?> SortedSetScoreAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SortedSetScoreAsync(GetPrefixedKey(key), json);
    }

    public async Task<long> SortedSetLengthAsync(string key)
    {
        return await _database.SortedSetLengthAsync(GetPrefixedKey(key));
    }

    public async Task<IEnumerable<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending)
    {
        var values = await _database.SortedSetRangeByRankAsync(GetPrefixedKey(key), start, stop, order);
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }

    public async Task<IEnumerable<T>> SortedSetRangeByScoreAsync<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending)
    {
        var values = await _database.SortedSetRangeByScoreAsync(GetPrefixedKey(key), start, stop, order: order);
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }
    #endregion

    #region 通用操作实现
    public async Task<bool> KeyDeleteAsync(string key)
    {
        return await _database.KeyDeleteAsync(GetPrefixedKey(key));
    }

    public async Task<bool> KeyExistsAsync(string key)
    {
        return await _database.KeyExistsAsync(GetPrefixedKey(key));
    }

    public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry)
    {
        return await _database.KeyExpireAsync(GetPrefixedKey(key), expiry);
    }

    public async Task<TimeSpan?> KeyTimeToLiveAsync(string key)
    {
        return await _database.KeyTimeToLiveAsync(GetPrefixedKey(key));
    }
    #endregion

    public void Dispose()
    {
        _redis?.Dispose();
    }
}

4.依赖注入

Program.cs中添加如下代码:

cs 复制代码
 // 配置Redis选项
 builder.Services.Configure<RedisOptions>(builder.Configuration.GetSection(RedisOptions.Redis));
 // 注册Redis服务
 builder.Services.AddSingleton<IRedisService, RedisService>();

5.控制器中使用

cs 复制代码
public class TestController : ControllerBase
{
    private readonly IRedisService _redis;
    private readonly IUserService _userService;
    public TestController(IRedisService redis, IUserService userService) 
    {
        _redis = redis;
        _userService = userService;
    }

    [HttpGet("string")]
    public async Task<IActionResult> TestString()
    {
        var user = await _userService.GetCurrentUserAsync();

        Console.WriteLine(user.TrueName);

        await _redis.StringSetAsync("anna","多慢慢流");
        var result = await _redis.StringGetAsync<string>("anna");
        return Ok(result);
    }

    [HttpGet("hash")]
    public async Task<IActionResult> TestHash()
    {
        string hkey = "fdm";
        await _redis.HashSetAsync(hkey, "fd1",new {Name="annadeville",Props="运动型" });
        await _redis.HashSetAsync(hkey,"fd2",new { Name="RR",Props="皮"});
        
        var all= await _redis.HashGetAllAsync<dynamic>(hkey);
        var fd1 = await _redis.HashGetAsync<dynamic>(hkey, "fd1");
        return Ok(new { All = all, Field1 = fd1 });
    }

}
相关推荐
闪电悠米8 小时前
黑马点评-Redis 消息队列-03_stream_consumer_group
开发语言·数据库·redis·分布式·缓存·junit·lua
qqxhb9 小时前
47|成本与性能:缓存、批处理、模型路由与降级
缓存·批处理·智能模型路由·多级降级预案·成本预算
佛祖让我来巡山11 小时前
线上 Redis 突然“爆”了,怎么办?
redis·redis宕机·redis崩了·redis线上事故
三十..12 小时前
Redis 核心原理与高可用架构实践
运维·数据库·redis
叶小鸡14 小时前
Java 篇-项目实战-AI 天机学堂(从 0 到 1)-day5
数据库·redis·缓存
大模型最新论文速读14 小时前
小红书提出 RedKnot:分头处理 kv 缓存,延时降低 60%效果还提升
论文阅读·人工智能·深度学习·机器学习·缓存·自然语言处理
IT策士14 小时前
Redis 从入门到精通:Python 操作 Redis
redis·python·bootstrap
周杰伦的稻香15 小时前
Go + Redis:本地部署高性能图片主色调提取服务
开发语言·redis·golang
大囚长16 小时前
大模型API的上下文缓存(Contextual Cache)
人工智能·缓存
小二·16 小时前
Redis 7 分布式缓存架构实战
redis·分布式·缓存