Common.Cache.MemoryCache
2.1.0
dotnet add package Common.Cache.MemoryCache --version 2.1.0
NuGet\Install-Package Common.Cache.MemoryCache -Version 2.1.0
<PackageReference Include="Common.Cache.MemoryCache" Version="2.1.0" />
<PackageVersion Include="Common.Cache.MemoryCache" Version="2.1.0" />
<PackageReference Include="Common.Cache.MemoryCache" />
paket add Common.Cache.MemoryCache --version 2.1.0
#r "nuget: Common.Cache.MemoryCache, 2.1.0"
#:package Common.Cache.MemoryCache@2.1.0
#addin nuget:?package=Common.Cache.MemoryCache&version=2.1.0
#tool nuget:?package=Common.Cache.MemoryCache&version=2.1.0
Common.Cache.MemoryCache
Common.Cache.MemoryCache 是一个基于 Microsoft.Extensions.Caching.Memory 的轻量封装,提供统一的缓存读写、批量删除和按模式删除能力。
功能特性
- 基于 ASP.NET Core
IMemoryCache - 支持字符串、对象、集合等多种缓存值
- 支持
GetOrCreateAsync - 支持批量删除和按通配符删除
- 支持获取当前由 Provider 管理的全部缓存键
- 支持 .NET 6.0 / 7.0 / 8.0 / 9.0 / 10.0
安装
Install-Package Common.Cache.MemoryCache
或:
dotnet add package Common.Cache.MemoryCache
服务注册
推荐使用 AddMemoryCacheStore:
services.AddMemoryCacheStore(options =>
{
options.DefaultExpiry = TimeSpan.FromSeconds(30);
options.CacheEmptyCollections = false;
options.FailThrowException = true; // 缓存操作失败时是否抛出异常(默认为true)
});
旧方法 AddMemoryCacheExtension 已标记为过时,但仍可继续使用:
services.AddMemoryCacheExtension(options =>
{
options.DefaultExpiry = TimeSpan.FromSeconds(30);
options.CacheEmptyCollections = false;
options.FailThrowException = true; // 缓存操作失败时是否抛出异常(默认为true)
});
基本使用
public class MyService
{
private readonly ICacheProvider _cacheProvider;
public MyService(ICacheProvider cacheProvider)
{
_cacheProvider = cacheProvider;
}
public async Task<UserInfo> GetUserAsync(string userId)
{
return await _cacheProvider.GetOrCreateAsync(
$"user:{userId}",
async () => await LoadUserFromDatabase(userId),
TimeSpan.FromMinutes(10));
}
}
读写缓存
await _cacheProvider.SetAsync("name", "azrng", TimeSpan.FromMinutes(5));
var name = await _cacheProvider.GetAsync("name");
var count = await _cacheProvider.GetAsync<int>("count");
var user = await _cacheProvider.GetAsync<UserInfo>("user:1");
GetOrCreateAsync
var count = await _cacheProvider.GetOrCreateAsync(
"counter",
() => 0,
TimeSpan.FromMinutes(1));
var user = await _cacheProvider.GetOrCreateAsync(
"user:1",
async () => await LoadUserFromDatabase("1"),
TimeSpan.FromMinutes(10));
批量操作
await _cacheProvider.RemoveAsync(new[] { "user:1", "user:2", "user:3" });
await _cacheProvider.RemoveMatchKeyAsync("user:*");
var allKeys = ((IMemoryCacheProvider)_cacheProvider).GetAllKeys();
var allValues = await ((IMemoryCacheProvider)_cacheProvider).GetAllAsync(allKeys);
await ((IMemoryCacheProvider)_cacheProvider).RemoveAllKeyAsync();
配置项
MemoryConfig 提供以下配置:
DefaultExpiry: 默认过期时间,默认值为 5 秒CacheEmptyCollections: 是否缓存空集合和空字符串,默认值为trueFailThrowException: 缓存操作失败时是否抛出异常,默认值为true
行为说明
1. 合法默认值会被正常缓存
从当前实现开始,0、false、DateTime.MinValue 这类合法业务值会被正常缓存,不再被误判为空值。
await _cacheProvider.SetAsync("bool:false", false);
var value = await _cacheProvider.GetAsync<bool>("bool:false"); // false
2. CacheEmptyCollections 只控制空集合和空字符串
当 CacheEmptyCollections = false 时:
null不会缓存- 空字符串不会缓存
- 空集合不会缓存
0、false等合法默认值仍然会缓存
3. 异常处理可通过配置控制
从 2.1.0 开始,可通过 FailThrowException 配置控制缓存操作失败时的行为:
true(默认):记录日志并抛出异常,避免把真实故障误判成”缓存未命中”false:记录日志并返回默认值,不抛出异常,提供更灵活的错误处理策略
4. 并发访问同一个 Key 时会做单 Key 同步
同一个 Key 在高并发下首次未命中时,Provider 会按 Key 做同步,避免多个线程同时重复执行工厂方法。
这能减少数据库或远程调用的重复压力。
5. RemoveMatchKeyAsync 使用通配符语义
RemoveMatchKeyAsync 不是正则表达式,而是通配符匹配:
*匹配任意多个字符?匹配任意单个字符[]匹配指定字符范围
示例:
await _cacheProvider.RemoveMatchKeyAsync("user:*");
await _cacheProvider.RemoveMatchKeyAsync("order:2026-03-??");
6. GetAllKeys 只返回当前 Provider 管理的键
GetAllKeys 不再通过反射读取 MemoryCache 内部私有字段,而是返回通过当前 Provider 写入并跟踪的键集合。
这意味着:
- 通过
IMemoryCache直接写入的键不会出现在GetAllKeys中 - 通过 Provider 删除、覆盖、驱逐的键会同步更新跟踪集合
- 实现更稳定,不依赖 .NET 运行时内部结构
注意事项
- 不建议使用
IEnumerable<T>、IQueryable<T>、IAsyncEnumerable<T>作为GetOrCreateAsync<T>的T - 如果需要缓存集合,请优先使用
List<T>或数组 SetAsync<T>(key, null)会返回false,不会写入缓存
版本更新记录
- 2.1.0
- 新增:
FailThrowException配置项,允许控制缓存操作失败时的行为true(默认):记录日志并抛出异常,与 2.0.0 行为一致false:记录日志并返回默认值,不抛出异常,提供更灵活的错误处理策略
- 优化:
GetOrCreateAsync支持FailThrowException配置,统一异常处理行为
- 新增:
- 2.0.0
- 破坏性更新:
GetOrCreateAsync发生异常时不再吞掉异常并返回default,改为记录日志后继续抛出异常 - 破坏性更新:
RemoveMatchKeyAsync改为按通配符语义匹配,支持*、?、[],不再直接把输入当作正则表达式 - 破坏性更新:
GetAllKeys改为返回当前 Provider 管理并跟踪的键,不再依赖反射读取MemoryCache内部私有字段 - 修复:支持缓存合法默认值,例如
0、false、DateTime.MinValue - 修复:
GetOrCreateAsync增加单 Key 并发保护,避免并发未命中时重复执行工厂方法 - 修复:
RemoveAsync(IEnumerable<string>)过滤空 key 和重复 key,并返回更准确的删除数量 - 优化:依赖注入注册改为复用同一个作用域内的
MemoryCacheProvider实例
- 破坏性更新:
- 1.3.2
- 更新异常信息输出
- 1.3.1
- 更新批量删除缓存的日志输出
- 1.3.0
- 修复 .NET 8 模糊匹配生效问题
- 引用 .NET 10 正式包
- 1.3.0-beta9
- 更新 .NET 10
- 1.3.0-beta8
- 修复设置不缓存空值时的问题
- 1.3.0-beta7
- 修复 GetOrCreateAsync 读取不到缓存仍写入的问题
- 1.3.0-beta6
- 更新命名空间
- 1.3.0-beta5
- 支持 .NET 9
- 移除对 netstandard2.1 的支持
- 更新注入方法
AddMemoryCacheStore
- 1.3.0-beta4
- 修改方法
KeyDeleteInBatchAsync为RemoveMatchKeyAsync - 修改方法
GetAllCacheKeys为GetAllKeys - 修改方法
RemoveCacheAllAsync为RemoveAllKeyAsync
- 修改方法
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. 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 is compatible. 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 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 is compatible. 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 is compatible. 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. |
-
net10.0
- Azrng.Cache.Core (>= 0.0.3)
- Microsoft.Extensions.Caching.Memory (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
-
net6.0
- Azrng.Cache.Core (>= 0.0.3)
- Microsoft.Extensions.Caching.Memory (>= 6.0.1)
- Microsoft.Extensions.DependencyInjection (>= 6.0.0)
-
net7.0
- Azrng.Cache.Core (>= 0.0.3)
- Microsoft.Extensions.Caching.Memory (>= 7.0.0)
- Microsoft.Extensions.DependencyInjection (>= 7.0.0)
-
net8.0
- Azrng.Cache.Core (>= 0.0.3)
- Microsoft.Extensions.Caching.Memory (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
-
net9.0
- Azrng.Cache.Core (>= 0.0.3)
- Microsoft.Extensions.Caching.Memory (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection (>= 9.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.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.1.0 | 69 | 3/26/2026 |
| 2.0.0 | 104 | 3/23/2026 |
| 1.3.2 | 312 | 12/17/2025 |
| 1.3.1 | 464 | 12/10/2025 |
| 1.3.0 | 367 | 11/30/2025 |
| 1.3.0-beta9 | 177 | 11/6/2025 |
| 1.3.0-beta8 | 208 | 10/9/2025 |
| 1.3.0-beta7 | 244 | 8/28/2025 |
| 1.3.0-beta5 | 204 | 7/14/2025 |
| 1.3.0-beta4 | 419 | 6/5/2024 |
| 1.3.0-beta3 | 183 | 2/9/2024 |
| 1.3.0-beta2 | 169 | 2/8/2024 |
| 1.3.0-beta11 | 292 | 11/12/2025 |
| 1.3.0-beta10 | 123 | 11/7/2025 |
| 1.3.0-beta1 | 297 | 11/14/2022 |
| 1.2.0 | 570 | 11/12/2022 |
| 1.1.1 | 628 | 7/9/2022 |
| 1.1.0 | 731 | 11/11/2020 |
| 1.0.1 | 627 | 10/9/2020 |
| 1.0.0 | 648 | 10/8/2020 |