MoneyTree.Caching 1.0.4
MoneyTree.Caching 缓存管理
📋 概述
MoneyTree.Caching 提供多级缓存管理能力,支持内存缓存、Redis 缓存以及两级混合缓存(L1 + L2),基于 Microsoft.Extensions.Caching 和 StackExchange.Redis 封装。
| 属性 | 说明 |
|---|---|
| NuGet 包 | MoneyTree.Caching |
| 外部依赖 | MoneyTree.Core、Microsoft.Extensions.Caching、StackExchange.Redis |
| 定位 | 多级缓存统一管理 |
🏗️ 项目文件结构
MoneyTree.Caching/
├── MoneyTree.Caching.csproj
├── GlobalUsings.cs
├── Abstractions/
│ ├── ICacheManager.cs # 缓存管理核心接口
│ └── ICacheKeyGenerator.cs # 缓存键生成器接口
├── Core/
│ ├── CacheOptions.cs # 缓存配置选项
│ ├── CacheEntryOptions.cs # 缓存项配置
│ └── CacheKeyGenerator.cs # 默认缓存键生成器实现
├── Providers/
│ ├── MemoryCacheProvider.cs # 内存缓存提供者
│ ├── RedisCacheProvider.cs # Redis 缓存提供者
│ └── HybridCacheProvider.cs # 混合缓存提供者(L1 + L2)
├── Extensions/
│ ├── CachingBuilder.cs # 流畅配置构造器
│ └── CachingExtensions.cs # DI 注册扩展
🚀 快速开始
使用 .NET HybridCache(推荐生产环境)
结合内存和 Redis 的两级缓存,兼顾性能与可靠性:
// Program.cs
using MoneyTree.Caching.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMoneyTreeCaching(c =>
{
c.UseHybrid(
connectionString: "redis:6379,password=xxx",
instanceName: "moneytree")
.WithDefaultExpiration(10)
.WithMaxLocalCacheSize(10000);
});
var app = builder.Build();
app.Run();
仅使用 Redis
builder.Services.AddMoneyTreeCaching(c =>
{
c.UseRedis("redis:6379", "moneytree");
});
使用内存缓存(开发环境)
builder.Services.AddMoneyTreeCaching(c =>
{
c.UseMemory();
});
📖 使用示例
基础缓存操作
public class OrderService
{
[Inject] public ICacheManager Cache { get; private set; } = default!;
// 获取或创建缓存
public async Task<Order?> GetOrderAsync(string id)
{
return await Cache.GetOrCreateAsync(
$"order:{id}",
async ct =>
{
// 从数据库查询
var order = await QueryDatabaseAsync(id, ct);
return order!;
},
CacheEntryOptions.FromMinutes(15));
}
// 失效单个缓存
public async Task InvalidateOrderCacheAsync(string id)
{
await Cache.RemoveAsync($"order:{id}");
}
// 批量失效缓存(按标签)
public async Task InvalidateAllOrdersAsync()
{
await Cache.RemoveByTagAsync("orders");
}
}
带标签的缓存
标签机制支持按业务维度批量失效缓存:
// 设置缓存时添加标签
await Cache.SetAsync(
$"order:{id}",
order,
new CacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30),
Tags = ["orders", $"customer:{customerId}"]
});
// 批量失效
await Cache.RemoveByTagAsync("orders"); // 删除所有订单缓存
await Cache.RemoveByTagAsync($"customer:{customerId}"); // 删除指定客户的缓存
使用 ICacheKeyGenerator 统一键名
通过 ICacheKeyGenerator 生成规范的缓存键名,避免散落各处的字符串拼接:
[Inject] public ICacheKeyGenerator KeyGenerator { get; private set; } = default!;
public async Task<Order?> GetOrderAsync(string id)
{
var key = KeyGenerator.GenerateEntityKey<Order>(id);
return await Cache.GetOrCreateAsync(key, async ct =>
{
var order = await QueryDatabaseAsync(id, ct);
return order!;
});
}
🏷️ 缓存标签最佳实践
| 场景 | 标签示例 | 说明 |
|---|---|---|
| 按实体类型 | orders |
失效所有订单缓存 |
| 按用户 | customer:{id} |
失效指定用户的所有缓存 |
| 按租户 | tenant:{id} |
多租户场景的隔离失效 |
| 按模块 | module:payment |
支付模块全局刷新 |
📊 缓存层级对比
| 层级 | 提供者 | 访问延迟 | 容量 | 持久化 |
|---|---|---|---|---|
| L1 内存 | MemoryCache | ~1μs | GB 级(进程内存) | ❌ |
| L2 分布式 | Redis | ~1ms | TB 级 | ✅ |
| 混合 L1+L2 | HybridCache | ~1μs(命中 L1) | GB + TB | ✅ |
No packages depend on MoneyTree.Caching.
.NET 10.0
- MoneyTree.Core (>= 1.0.4)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Caching.Hybrid (>= 10.8.0)
- Microsoft.Extensions.Caching.Memory (>= 10.0.10)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.10)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- StackExchange.Redis (>= 3.0.17)