Asp.Net Core基于StackExchange Redis 缓存

news2025/6/9 7:20:46

NuGet安装

StackExchange.Redis

Microsoft.Extensions.Options

0. appsettings.json初始化配置

{
  "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初始化对象

/// <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.接口

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. 实现

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中添加如下代码:

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

5.控制器中使用

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 });
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2405100.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kafka(windows)

目录 介绍 下载 配置 测试 介绍 Kafka是一个分布式流媒体平台&#xff0c;类似于消息队列或企业信息传递系统。 下载 Kafka对于Zookeeper是强依赖&#xff0c;所以安装Kafka之前必须先安装zookeeper 官网&#xff1a;Apache Kafka 下载此安装包并解压 配置 新建log…

基于安卓的文件管理器程序开发研究源码数据库文档

摘 要 伴随着现代科技的发展潮流&#xff0c;移动互联网技术快速发展&#xff0c;各种基于通信技术的移动终端设备做的也越来越好了&#xff0c;现代智能手机大量的进入到了我们的生活中。电子产品的各种软硬技术技术的发展&#xff0c;操作系统的不断更新换代&#xff0c;谷歌…

EMC VNXe 存储系统日志收集方法

写在前面 有朋友找来看看VNXe的故障&#xff0c;这种问题总是要收集日志&#xff0c;顺便这里也分享给大家。 注意&#xff0c;VNXe和VNX 属于完全不同的产品&#xff0c;不要看名字很类似&#xff0c;操作系统已经完全重构了&#xff0c;如果说是否有联系&#xff0c;大概就…

从“人找政策”到“政策找人”:智能退税ERP数字化重构外贸生态

离境退税新政核心内容与外贸企业影响 &#xff08;一&#xff09;政策核心变化解析 退税商店网络扩容 新政明确鼓励在大型商圈、旅游景区、交通枢纽等境外旅客聚集地增设退税商店&#xff0c;并放宽备案条件至纳税信用M级企业。以上海为例&#xff0c;静安区计划新增1000家退…

以人类演示视频为提示,学习可泛化的机器人策略

25年5月来自清华大学、上海姚期智研究院和星动纪元&#xff08;RoboEra&#xff09;公司的论文“Learning Generalizable Robot Policy with Human Demonstration Video as a Prompt”。 最近的机器人学习方法通​​常依赖于从通过遥操作收集的大量机器人数据集中进行模仿学习…

SOC-ESP32S3部分:36-适配自己的板卡

飞书文档https://x509p6c8to.feishu.cn/wiki/RP4UwPrsKi4xuQkKLAAcKxD3n1b 如果你自己画了PCB板&#xff0c;需要把自己绘制的板卡配置小智AI工程&#xff0c;可以参考此文档。 下载源码 克隆或下载源码到本地&#xff0c;这里以1.5.5为例&#xff0c;大家可以自行修改其它版…

LLMs 系列科普文(8)

八、模型的自我认知 接下来我们聊聊另一种问题&#xff0c;即模型的自我认知。 网上经常经常可以看到人们会问大语言模型一些关于认知方面的问题&#xff0c;比如“你是什么模型&#xff1f;谁创造了你&#xff1f;” 说实话&#xff0c;其实这个问题有点无厘头。 之所以这么…

机器学习基础相关问题

机器学习相关的基础问题 K-means是否一定会收敛 K-means是否一定会收敛 K-means算法在有限步数内一定会收敛&#xff0c;但收敛到的可能是局部最优解而非全局最优解。以下是详细分析&#xff1a; K-means 的优化目标是最小化 样本到其所归属簇中心的距离平方和&#xff08;SSE…

验证负载均衡与弹性伸缩

什么是弹性伸缩&#xff08;Auto Scaling&#xff09;&#xff1f; 弹性伸缩是指 云计算平台根据实时负载自动调整计算资源&#xff08;如服务器实例、容器Pod&#xff09;数量&#xff0c;以确保系统在高峰时保持稳定&#xff0c;在低谷时节省成本。 什么时候会触发弹性伸缩&…

Three.js中AR实现详解并详细介绍基于图像标记模式AR生成的详细步骤

文档地址 Three.js中AR实现详解 以下是Three.js中实现AR功能的详细解析&#xff0c;涵盖技术原理、实现步骤、核心组件及优化策略&#xff1a; &#x1f9e9; 一、技术基础 AR.js框架的核心作用 AR.js是Three.js实现AR的基石&#xff0c;提供以下核心能力&#xff1a; 多模…

GeoBoundaries下载行政区划边界数据(提供中国资源shapefile)

要下载山东省济南市各个区的行政区划边界数据&#xff0c;你可以通过 geoBoundaries 提供的数据来实现。下面是详细步骤&#xff0c;包括网页操作和可选的 Python 自动化方式。 目录 ✅ 一、通过 geoBoundaries 官网手动下载1. 打开官网&#xff1a;2. 查找中国数据&#xff1a…

大模型如何选型?嵌入模型如何选型?

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 有很多很多不足的地方&#xff0c;欢迎评论交流&#xff0c;感谢您的阅读和评论&#x1f604;。 目录 引言模型优劣认知与模型选择大模型&#xff08;L…

开源大模型网关:One API实现主流AI模型API的统一管理与分发

以下是对One API的简单介绍&#xff1a; One API是一个使用go语言开发的大语言模型 API 管理与分发系统支持Docker一键快速部署&#xff0c;且资源占用小&#xff0c;高性能开箱支持多平台大模型快速接入&#xff0c;包括OpenAI、Gemini、xAI、Grop、Anthropic Claude、Ollama…

智慧充电:新能源汽车智慧充电桩的发展前景受哪些因素影响?

全球能源结构转型与碳中和目标的推进&#xff0c;新能源汽车产业迎来爆发式增长&#xff0c;而智慧充电桩作为其核心基础设施&#xff0c;发展前景备受关注。智慧充电不仅关乎用户充电体验的优化&#xff0c;更是电网平衡、能源效率提升的关键环节。 然而&#xff0c;其发展并…

【网站建设】不同类型网站如何选择服务器?建站项目实战总结

做了几个建站项目后,深刻体会到一件事:不同类型的网站,所采用的服务器策略是完全不同的。 如果选错了服务器方案,可能带来过高的成本、过低的性能,甚至上线失败。 这篇文章分享一下我在实战中的经验,供正在做建站项目的朋友参考。 🚩 1️⃣ 纯展示型网站 —— 静态服务…

iptables实验

实验一&#xff1a;搭建web服务&#xff0c;设置任何人能够通过80端口访问。 1.下载并启用httpd服务器 dnf -y install httpd 开启httpd服务器 systemctl start httpd 查看是否启用 下载并启用iptables&#xff0c;并关闭firewalld yum install iptable…

前后端分离开发 和 前端工程化

来源&#xff1a;黑马程序员JavaWeb开发教程&#xff0c;实现javaweb企业开发全流程&#xff08;涵盖SpringMyBatisSpringMVCSpringBoot等&#xff09;_哔哩哔哩_bilibili 前后端混合开发&#xff1a; 需要使用前端的技术栈开发前端的功能&#xff0c;又需要使用Java的技术栈…

web端rtmp推拉流测试、抽帧识别计数,一键式生成巡检报告

本文旨在实现无人机城市交通智慧巡检中的一个模块——无人机视频实时推拉流以及识别流并在前端展示&#xff0c;同时&#xff0c;统计目标数量以及违停数量&#xff0c;生成结果评估&#xff0c;一并发送到前端展示。对于本文任何技术上的空缺&#xff0c;可在博主主页前面博客…

Excel 表格内批量添加前缀与后缀的实用方法

我们经常需要为 Excel 表格中的内容统一添加前缀或后缀&#xff0c;例如给编号加“NO.”、给姓名加“会员_”等。手动操作效率低&#xff0c;本文将介绍几种实用的方法&#xff0c;帮助你快速完成批量添加前缀和后缀的操作。 使用“&”运算符添加前缀或后缀&#xff08;推…

2024 CKA题库+详尽解析| 15、备份还原Etcd

目录 免费获取题库配套 CKA_v1.31_模拟系统 15、 备份还原Etcd 题目&#xff1a; 开始操作: 1&#xff09;、切换集群 2&#xff09;、登录master并提权 3&#xff09;、备份Etcd现有数据 4&#xff09;、验证备份数据快照 5&#xff09;、查看节点和Pod状态 6&am…