Lycoris.CSRedisCore.Extensions 8.2.0

dotnet add package Lycoris.CSRedisCore.Extensions --version 8.2.0
                    
NuGet\Install-Package Lycoris.CSRedisCore.Extensions -Version 8.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Lycoris.CSRedisCore.Extensions" Version="8.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Lycoris.CSRedisCore.Extensions" Version="8.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Lycoris.CSRedisCore.Extensions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Lycoris.CSRedisCore.Extensions --version 8.2.0
                    
#r "nuget: Lycoris.CSRedisCore.Extensions, 8.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Lycoris.CSRedisCore.Extensions@8.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Lycoris.CSRedisCore.Extensions&version=8.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Lycoris.CSRedisCore.Extensions&version=8.2.0
                    
Install as a Cake Tool

Lycoris.CSRedisCore.Extensions

NuGet License

基于 CSRedisCore 的二次封装库,为不熟悉 Redis 命令的开发者提供简洁、类型安全的 C# API。内置 JSON 序列化、分布式锁、队列、发布/订阅、Redis 监控等常用场景支持。

特性

  • 强类型 API — 支持泛型读写,自动 JSON 序列化/反序列化
  • 多数据类型 — String、Hash、List、Set、Sorted Set 全覆盖
  • 单实例 / 多实例 — 静态类快速调用,工厂模式管理多 Redis 连接
  • 分布式锁 — 带看门狗(Watchdog)自动续期,防止死锁
  • 队列封装 — 入队/出队、去重、移除、计数
  • 发布/订阅 — 普通订阅 & 模式订阅(通配符),集群兼容
  • 有序集合增强 — 按分数范围查询、排名、弹出最高/最低分成员
  • Redis 监控 — 解析 INFO 命令,返回结构化 Server / Memory / CPU / Stats / Keyspace 信息
  • 事务 & 管道 — 类型化管道 API(与 RedisCache 一致的调用风格),支持批量操作、Lua 脚本执行
  • 缓存穿透保护CacheShell 空值缓存
  • Key 前缀 — 自动为所有 Key 添加统一前缀,便于多项目共用
  • 哨兵模式 — 支持 Redis Sentinel 高可用部署
  • 安全序列化 — 内置 longstringdecimalstring 转换器,防止前端精度丢失

安装

dotnet add package Lycoris.CSRedisCore.Extensions

快速开始

单实例

// 注册(Program.cs 中调用一次)
CSRedisCoreBuilder.AddSingleRedisInstance(opt =>
{
    opt.Host = "127.0.0.1";
    opt.Port = 6379;
    opt.Password = "your-password";
    opt.Prefix = "MyApp";       // Key 前缀,自动变为 "MyApp:"
});

// 使用
await RedisCache.String.SetAsync("user:1", new { Name = "Alice" }, TimeSpan.FromMinutes(10));
var user = await RedisCache.String.GetAsync<User>("user:1");

多实例

// 注册
CSRedisCoreBuilder.AddMultipleRedisInstance("cache", opt =>
{
    opt.Host = "cache-server";
    opt.Port = 6379;
});

CSRedisCoreBuilder.AddMultipleRedisInstance("session", opt =>
{
    opt.Host = "session-server";
    opt.Port = 6380;
    opt.UseDatabase = 1;
});

// 使用
var cache = RedisCacheFactory.GetInstance("cache");
var session = RedisCacheFactory.GetInstance("session");

await cache.String.SetAsync("key", "value");
await session.String.SetAsync("token", "xxx");

API 概览

所有 API 均提供同步与异步版本。以下以静态类 RedisCache 为例,多实例通过 RedisCacheFactory.GetInstance(name) 获取的 RedisCacheService 实例拥有相同接口。

String 操作 RedisCache.String

// 写入
await RedisCache.String.SetAsync("key", "value", TimeSpan.FromMinutes(5));
await RedisCache.String.SetAsync("user", userObj);

// 仅当 key 不存在/已存在时才设置
await RedisCache.String.SetIfNotExistsAsync("lock", "1", TimeSpan.FromSeconds(30));
await RedisCache.String.SetIfExistsAsync("key", "newvalue");

// 读取
string val = await RedisCache.String.GetAsync("key");
User user = await RedisCache.String.GetAsync<User>("user");

// 批量操作
await RedisCache.String.MultipleSetAsync("k1", "v1", "k2", "v2");
List<string> values = await RedisCache.String.MultipleGetAsync("k1", "k2");

// 目录批量获取
List<User> allUsers = await RedisCache.String.MultipleGetAsync<User>("user");

// 原子增减
long count = await RedisCache.String.AdditionAsync("counter", 1);
long remain = await RedisCache.String.SubtractionAsync("stock", 5);

// 字符串操作
long len = await RedisCache.String.StringLengthAsync("key");
long newLen = await RedisCache.String.AppendAsync("key", "-suffix");
string sub = await RedisCache.String.GetRangeAsync("key", 0, 10);
await RedisCache.String.SetRangeAsync("key", 5, "replace");

// 原始字节读写(无需 JSON 序列化,适合二进制数据/二进制协议)
await RedisCache.String.SetBytesAsync("binary", byteArray, TimeSpan.FromMinutes(5));
byte[] bytes = await RedisCache.String.GetBytesAsync("binary");

Hash 操作 RedisCache.Hash

// 设置字段
await RedisCache.Hash.SetAsync("user:1", "name", "Alice");
await RedisCache.Hash.SetAsync("user:1", ("name", "Bob"), ("age", "30"));

// 获取字段
string name = await RedisCache.Hash.GetAsync("user:1", "name");

// 获取全部字段
Dictionary<string, string> all = await RedisCache.Hash.GetAllAsync("user:1");

// 仅当字段不存在才设置
await RedisCache.Hash.SetNxAsync("user:1", "role", "admin");

// 字段增减(整数/浮点)
await RedisCache.Hash.AdditionAsync("user:1", "score", 10);
await RedisCache.Hash.IncrByFloatAsync("user:1", "balance", 1.5m);

// 获取所有值 / 字段值长度
List<string> values = await RedisCache.Hash.ValuesAsync("user:1");
long len = await RedisCache.Hash.FieldStringLengthAsync("user:1", "name");

// 迭代大型 Hash
var scan = await RedisCache.Hash.ScanAsync("user:1", 0, count: 100);

List 操作 RedisCache.List

// 头部插入 / 尾部插入
await RedisCache.List.SetFirstAsync("queue", "item1");
await RedisCache.List.SetLastAsync("queue", "item2");

// 弹出
string first = await RedisCache.List.GetAndRemoveFirstAsync("queue");
string last = await RedisCache.List.GetAndRemoveLastAsync("queue");

// 获取全部 / 区间元素
List<string> all = await RedisCache.List.GetAllAsync("queue");
List<string> range = await RedisCache.List.GetRangeAsync("queue", 0, 9);

// 按索引操作
string item = await RedisCache.List.GetByIndexAsync("queue", 3);
await RedisCache.List.SetByIndexAsync("queue", 3, "newvalue");

// 插入(在指定元素前/后)
await RedisCache.List.InsertBeforeAsync("queue", "pivot", "newitem");
await RedisCache.List.InsertAfterAsync("queue", "pivot", "newitem");

// 列表信息
long len = await RedisCache.List.LengthAsync("queue");

// 移除与裁剪
long removed = await RedisCache.List.RemoveAsync("queue", 0, "item1"); // 移除所有匹配
await RedisCache.List.TrimAsync("queue", 0, 99); // 保留前100个

// 转移元素
string moved = await RedisCache.List.PopLastPushFirstAsync("source", "target");

Set 操作 RedisCache.Set

// 添加 / 移除
await RedisCache.Set.SetAsync("tags", "redis", "csharp", "dotnet");
await RedisCache.Set.RemoveAsync("tags", "csharp");

// 查询
long count = await RedisCache.Set.CountAsync("tags");
bool exists = await RedisCache.Set.ExistsAsync("tags", "redis");
List<string> all = await RedisCache.Set.GetAllAsync("tags");

// 随机获取(不移除)
string r = await RedisCache.Set.RandomMemberAsync("tags");
string[] rs = await RedisCache.Set.RandomMembersAsync("tags", 3);

// 随机弹出(移除)
string popped = await RedisCache.Set.GetRandomAsync("tags");

// 移动成员
await RedisCache.Set.MoveAsync("tags", "archive", "redis");

// 集合运算
string[] diff = await RedisCache.Set.DifferenceAsync("a", "b");   // 差集
string[] inter = await RedisCache.Set.IntersectionAsync("a", "b"); // 交集
string[] union = await RedisCache.Set.UnionAsync("a", "b");       // 并集
await RedisCache.Set.IntersectionStoreAsync("dest", "a", "b");   // 交集存储到新集合

// 迭代大型集合
var scan = await RedisCache.Set.ScanAsync("tags", 0, count: 100);

Sorted Set 操作 RedisCache.Sort

// 添加(单个/批量)
await RedisCache.Sort.AddAsync("leaderboard", "player1", 100);
await RedisCache.Sort.SetMultipleAsync("leaderboard", (200, "p2"), (300, "p3"));

// 按分数范围查询
var top10 = await RedisCache.Sort.GetRevRangeByScoreWithScoresAsync("leaderboard", 1000, 0, count: 10);

// 按排名查询(升序/降序)
var rankRange = await RedisCache.Sort.GetRangeByRankWithScoresAsync("leaderboard", 0, 9);
var revRankRange = await RedisCache.Sort.GetRevRangeByRankWithScoresAsync("leaderboard", 0, 9);

// 排名 & 分数(降序/升序)
long? rank = await RedisCache.Sort.RankAsync("leaderboard", "player1");          // 降序
long? rankAsc = await RedisCache.Sort.RankAscendingAsync("leaderboard", "player1"); // 升序
decimal? score = await RedisCache.Sort.GetScoreAsync("leaderboard", "player1");

// 统计分数区间
long cnt = await RedisCache.Sort.CountByScoreAsync("leaderboard", 100, 500);

// 弹出最高分 / 最低分成员
string[] max = await RedisCache.Sort.MaxAsync("leaderboard", 3);
string[] min = await RedisCache.Sort.MinAsync("leaderboard", 3);

// 按分数区间移除
await RedisCache.Sort.RemoveByScoreAsync("leaderboard", 0, 50);

// 迭代大型有序集合
var scan = await RedisCache.Sort.ScanAsync("leaderboard", 0, count: 100);

分布式锁 RedisCache.Utils

// 尝试获取锁(未拿到立即返回 null)
var redisLock = await RedisCache.Utils.LockAsync("resource-key", timeout: 30, autoDelay: true);
if (redisLock.IsLock)
{
    // 执行临界区代码
    redisLock.Unlock();
}

// 带超时等待的锁
var redisLock = await RedisCache.Utils.TryLockAsync(getTimeout: 5, "resource-key", timeout: 30);

autoDelay: true 开启看门狗线程,自动续期直到显式调用 Unlock(),进程异常退出不会导致死锁。

队列操作 RedisCache.Utils

// 入队(默认去重)
await RedisCache.Utils.EnqueueAsync("tasks", taskObj);
await RedisCache.Utils.EnqueueAsync("tasks", taskObj, checkDuplicate: false);

// 出队
var task = await RedisCache.Utils.DequeueAsync<Task>("tasks");

// 队列长度
long len = await RedisCache.Utils.QueueCountAsync("tasks");

// 移除指定元素
await RedisCache.Utils.RemoveValueFromQueueAsync("tasks", targetObj);

// 检查元素是否存在
bool exists = await RedisCache.Utils.CheckValueExitsFromQueueAsync("tasks", targetObj);

键管理 RedisCache.Key

bool exists = await RedisCache.Key.ExistsAsync("key");
await RedisCache.Key.ExpireAsync("key", TimeSpan.FromMinutes(30));
await RedisCache.Key.ExpireAtAsync("key", DateTime.Now.AddHours(1)); // Unix 时间戳过期
long ttl = await RedisCache.Key.TTLAsync("key");      // 秒
long pttl = await RedisCache.Key.PTTLAsync("key");     // 毫秒
await RedisCache.Key.PExpireAsync("key", 5000);         // 毫秒过期
await RedisCache.Key.PersistAsync("key");               // 移除过期时间
await RedisCache.Key.RenameAsync("old", "new");
await RedisCache.Key.RemoveAsync("key1", "key2");
string[] keys = await RedisCache.Key.GetKeysAsync("user:*");
var type = await RedisCache.Key.TypeAsync("key");       // KeyType 枚举
var random = await RedisCache.Key.RandomKeyAsync();
var allKeys = await RedisCache.Key.GetAllRedisKeysInfoAsync(); // 全量 key 列表 + 类型 + TTL

// 游标迭代(安全遍历大量 key)
var scan = await RedisCache.Key.ScanAsync(0, "user:*", count: 100);

发布/订阅 RedisCache.Message

// 发布
RedisCache.Message.Publish("channel", new { Type = "notify", Content = "hello" });

// 订阅
var sub = RedisCache.Message.Subscribe("channel", msg => Console.WriteLine(msg));
var subT = RedisCache.Message.Subscribe<MyMsg>("channel", obj => Console.WriteLine(obj.Type));

// 模式订阅(通配符,集群安全)
var psub = RedisCache.Message.PSubscribe(e => Console.WriteLine(e.Body), "order:*", "user:*");

监控 RedisCache.Monitor

var info = await RedisCache.Monitor.GetInfoAsync();

Console.WriteLine($"Redis 版本: {info.Server.RedisVersion}");
Console.WriteLine($"运行天数: {info.Server.UptimeInDays}");
Console.WriteLine($"内存使用: {info.Memory.UsedMemoryHuman}");
Console.WriteLine($"内存负载: {info.Memory.LoadDescription}");
Console.WriteLine($"缓存命中率: {info.Stats.LoadDescription}");
Console.WriteLine($"QPS: {info.Stats.InstantaneousOpsPerSec}");
Console.WriteLine($"客户端连接: {info.Clients.ConnectedClients}");
Console.WriteLine($"CPU 负载: {info.Cpu.LoadDescription}");

事务 & Lua 脚本 RedisCache.Utils

// 类型化管道事务(推荐)— API 风格与 RedisCache 一致
var results = await RedisCache.Utils.PipeExecuteAsync(cache =>
{
    cache.String.SetAsync("k1", "v1");
    cache.String.AdditionAsync("counter", 1);
    cache.Hash.SetAsync("h1", "f1", "v1");
    return Task.CompletedTask;
});
// 注意:回调内不可 await 单个操作,所有命令排队后在回调返回时批量执行

// 原始管道事务(兼容旧版)
var results = await RedisCache.Utils.PipeExecuteAsync(async pipe =>
{
    await pipe.SetAsync("k1", "v1");
    await pipe.IncrByAsync("counter", 1);
});

// Lua 脚本
object luaResult = await RedisCache.Utils.RunLuaScriptAsync(
    "return redis.call('GET', KEYS[1])", "mykey");

缓存穿透防护 RedisCacheService.CacheShell

// 多实例模式下
var svc = RedisCacheFactory.GetInstance("cache");
string data = await svc.CacheShell("key", TimeSpan.FromMinutes(5), async () =>
{
    return await FetchFromDbAsync(); // 穿透时回调
});

配置选项

参数 类型 默认值 说明
Host string Redis 服务地址
Port int Redis 端口
UserName string Redis 6.0+ ACL 用户名
Password string 连接密码
UseDatabase int 0 数据库编号
SSL bool false 是否启用 SSL
TestCluster bool false 是否检测集群(阿里云/腾讯云集群需设为 false
Prefix string 全局 Key 前缀
Poolsize int 50 连接池大小
IdleTimeout int 20000 连接空闲超时 (ms)
ConnectTimeout int 5000 连接超时 (ms)
SyncTimeout int 10000 发送/接收超时 (ms)
AutoDispose bool true 跟随进程退出自动释放
RetryOnFailure int 0 失败重试次数
Preheat int 0 连接池预热连接数
AsyncPipeline bool false 是否自动使用异步 Pipeline
NewtonsoftJsonSerializerSettings JsonSerializerSettings 自定义 JSON 序列化配置
UseSentinels(params string[]) 方法 启用哨兵模式

哨兵模式

CSRedisCoreBuilder.AddSingleRedisInstance(opt =>
{
    opt.Password = "pwd";
    opt.UseSentinels("127.0.0.1:26379", "127.0.0.1:26380", "127.0.0.1:26381");
});

JSON 序列化

默认配置:

  • CamelCase 属性命名
  • 日期格式 yyyy-MM-dd HH:mm:ss.ffffff
  • 忽略 null
  • long / decimal 输出为字符串(防止前端精度丢失)
  • 最大嵌套深度 200

可通过 NewtonsoftJsonSerializerSettings 覆盖:

CSRedisCoreBuilder.AddSingleRedisInstance(opt =>
{
    opt.Host = "127.0.0.1";
    opt.Port = 6379;
    opt.NewtonsoftJsonSerializerSettings = new JsonSerializerSettings
    {
        // 你的自定义配置
    };
});

直接访问底层 CSRedisClient

// 单实例
var rawClient = RedisCache.CSRedisClient;

// 多实例
var rawClient = RedisCacheFactory.GetInstance("name").CSRedisClient;

许可

MIT

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.2.0 90 5/18/2026
8.0.7 113 3/29/2026
8.0.6 116 3/27/2026
8.0.5 113 3/18/2026
8.0.4 126 2/6/2026
8.0.3-rc 111 2/6/2026
8.0.2 139 1/4/2026
8.0.1 253 10/22/2025
8.0.0 283 8/30/2025
6.2.0-rc 160 12/10/2024
6.1.6 236 11/18/2024
6.1.6-rc 184 9/18/2024
6.1.5 268 9/18/2024
6.1.5-rc 189 9/17/2024
6.1.4 240 5/28/2024
6.1.3-rc 187 4/11/2024
6.1.2 261 4/11/2024
6.1.2-rc 174 4/10/2024
6.1.1 250 4/9/2024
Loading failed