Grace.Cache
1.0.0.4
dotnet add package Grace.Cache --version 1.0.0.4
NuGet\Install-Package Grace.Cache -Version 1.0.0.4
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="Grace.Cache" Version="1.0.0.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Grace.Cache" Version="1.0.0.4" />
<PackageReference Include="Grace.Cache" />
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 Grace.Cache --version 1.0.0.4
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Grace.Cache, 1.0.0.4"
#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 Grace.Cache@1.0.0.4
#: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=Grace.Cache&version=1.0.0.4
#tool nuget:?package=Grace.Cache&version=1.0.0.4
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Grace.Cache
基于 ABP(Volo.Abp)和 FreeRedis 的 Redis 缓存模块封装。
安装
dotnet add package Grace.Cache
配置
在 appsettings.json 中添加 Redis 连接配置:
{
"Redis": {
"Configuration": "127.0.0.1:6379,defaultDatabase=0,poolsize=5,ssl=false"
}
}
连接字符串参数:
| 参数 | 说明 |
|---|---|
password |
Redis 密码 |
defaultDatabase |
默认数据库(0-15) |
poolsize |
连接池大小(默认 5) |
ssl |
是否启用 SSL |
preheat |
是否预热连接 |
使用
1. 注册模块
在项目的 AbpModule 中添加 DependsOn:
[DependsOn(typeof(GraceCacheModule))]
public class MyApplicationModule : AbpModule
{
}
2. 注入并使用
public class MyService : ITransientDependency
{
private readonly CachingRedisClient _cache;
public MyService(CachingRedisClient cache)
{
_cache = cache;
}
public async Task DoSomething()
{
// 字符串操作
await _cache.RedisClient.SetAsync("key", "value");
var val = await _cache.RedisClient.GetAsync("key");
// 对象序列化(自动使用 System.Text.Json)
await _cache.RedisClient.SetAsync("user:1", new User { Name = "Alice" });
var user = await _cache.RedisClient.GetAsync<User>("user:1");
// 删除
await _cache.RedisClient.DelAsync("key");
// 设置过期时间
await _cache.RedisClient.ExpireAsync("key", 60);
}
}
3. FreeRedis 常用操作
var redis = _cache.RedisClient;
// 字符串
redis.Set("key", "value");
string val = redis.Get("key");
// 哈希
redis.HSet("hash", "field", "value");
string hval = redis.HGet("hash", "field");
// 列表
redis.LPush("list", "a", "b");
string[] items = redis.LRange("list", 0, -1);
// 发布/订阅
redis.Subscribe("channel", (_, msg) => Console.WriteLine(msg));
redis.Publish("channel", "hello");
// 管道
redis.Pipeline(p =>
{
p.Set("key1", "val1");
p.Set("key2", "val2");
});
所有操作均支持 Async 后缀的异步方法。
4. 资源池(ResourcePool)
为什么需要 ResourcePool?
实际项目中经常遇到:同一份数据在同一个请求内被多次读取。例如:
- 当前用户信息,多个 Service 都会调用
- 字典表/配置表,数据不变但多次查询
- 远程 API 或数据库查询结果暂时复用
如果每次都走 Redis 或数据库,重复请求增加延迟和负载。ResourcePool 提供 请求级别的内存缓存,在同一个 Scoped 范围内复用已加载的数据。
核心价值
| 特性 | 说明 |
|---|---|
| 一次加载,多处复用 | 同一标识的资源仅在首次调用时执行 loadFunc,后续直接返回缓存结果 |
| 并发等待 | 多个线程同时请求同一未缓存资源时,只有一个执行 loadFunc,其余自动等待已完成的任务 |
| Scoped 生命周期 | 缓存随请求结束自动释放(IScopedDependency),不同请求之间不共享,无需手动清理 |
| 类型安全 | 泛型方法 GetAsync<T> 带类型约束,不同资源类型自动加前缀,同名键不冲突 |
使用场景
场景 1:避免重复查询用户信息
在同一请求中,多个 Service 都可能获取当前用户信息:
public class CurrentUserService : ITransientDependency
{
private readonly IResourcePool _pool;
private readonly CachingRedisClient _cache;
public CurrentUserService(IResourcePool pool, CachingRedisClient cache)
{
_pool = pool;
_cache = cache;
}
public async Task<UserProfile> GetCurrentUserAsync(long userId)
{
return await _pool.GetAsync($"user:{userId}", async () =>
{
// 第一次调用时执行,后续调用直接返回内存缓存
var json = await _cache.RedisClient.GetAsync($"user:{userId}");
return JsonSerializer.Deserialize<UserProfile>(json);
});
}
}
场景 2:批量加载配置/字典数据
public class ConfigService : ITransientDependency
{
private readonly IResourcePool _pool;
private readonly CachingRedisClient _cache;
public ConfigService(IResourcePool pool, CachingRedisClient cache)
{
_pool = pool;
_cache = cache;
}
public async Task<List<City>> GetCitiesAsync()
{
// 同一请求内多次调用只查一次 Redis
return await _pool.GetAsync("city_list", async () =>
{
return await _cache.RedisClient.GetAsync<List<City>>("dict:cities")
?? new List<City>();
});
}
}
场景 3:远程 API 防重复调用
public async Task<WechatToken> GetAccessTokenAsync()
{
return await _pool.GetAsync("wechat:access_token", async () =>
{
var resp = await _httpClient.GetFromJsonAsync<WechatToken>(
"https://api.weixin.qq.com/cgi-bin/token");
return resp;
});
}
使用技巧
- 键自动按类型隔离:
GetAsync<T>("id")实际存储键为typeof(T).FullName + "_" + id,不同类型即使id相同也不会冲突。 - Guid 直传:
GetAsync<T>(guid, loadFunc)无需手动ToString()。 - 同步/异步按需选择:
- 异步优先:
await _pool.GetAsync("key", async () => await FetchAsync()) - 同步数据:
_pool.Get("key", () => FetchSync())
- 异步优先:
- 两层缓存组合:
ResourcePool做请求级内存缓存 +CachingRedisClient做跨请求 Redis 缓存,减少重复查询。 - 不要跨请求复用:
ResourcePool是IScopedDependency,生命周期与请求绑定,不适合存放跨请求数据(请直接使用 Redis)。
## 依赖
- [FreeRedis](https://github.com/2881099/FreeRedis) — Redis 客户端
- [Volo.Abp.Core](https://abp.io) — ABP 框架
- .NET 8 +
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- FreeRedis (>= 1.2.0 && < 2.0.0)
- Grace.Extensions (>= 1.0.0.6)
- Volo.Abp.Core (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.