Skip to content

Fast.Cache

逐成员 API、参数与返回参考

版本 3.5.33;目标 net8.0net9.0net10.0;依赖 Fast.RuntimeCSRedisCore。这是 Redis 客户端封装,注册成功不代表连接可用。

bash
dotnet add package Fast.Cache

注册与配置

services.AddCache(string section = "RedisSettings") 注册 ICache 及被发现的 ICache<TLocator> 单例。另一个重载接受 Action<RedisSettingsOptions>,默认连接直接配置在选项上,命名连接写入 Services

当前列表回调已经绑定到缓存实现读取的 IOptionsMonitor<RedisSettingsOptions>;第一项为默认配置,后续具名项进入 Services。配置节点和回调最终使用相同选项类型。

选项后配置默认值
ServiceIp127.0.0.1
Port6379
DbName0
Poolsize100
SSLfalse
DbPwdPrefix无默认值
Services空列表;条目类型 RedisServiceSettingsOptions,额外包含 ServiceName

ICacheContextLocator 用于配置定位;DefaultCacheContextLocator 为默认定位器。自定义泛型定位器须满足 new() 约束,ServiceName 用于匹配 Services 条目,未找到对应服务会抛 InvalidOperationException。生产配置由宿主注入,不将密码写入示例或仓库。

ICache 与 ICache<TLocator>

API 家族参数与返回
PrefixClientContextLocator分别提供前缀、底层 CSRedisClient 与定位器
Get/Get<T>GetAsync/GetAsync<T>按键读取字符串或指定类型;异步返回 Task<string> / Task<T>
Exists/ExistsAsync按键判断存在,返回 bool / Task<bool>
Set/SetAsync(key, object value)、追加 int expireSecondsTimeSpan expireTimeSpan 三组重载;返回写入成功标志
GetAndSet/GetAndSet<T>缺失时调用同步值工厂并缓存;可指定秒数或 TimeSpan
GetAndSetAsync/GetAndSetAsync<T>工厂为 Func<Task<string>> / Func<Task<T>>;需等待返回任务
Del/DelAsync(params string[] key)返回实际删除数 long / Task<long>
DelByPattern/DelByPatternAsync按模式扫描并删除,返回实际删除数;不是廉价的单键操作
GetAllKeys/GetAllKeysAsync返回 List<string> / 对应任务;扫描数据库,避免高频调用

下面是消费代码结构,不在文档检查时连接 Redis:

csharp
using Fast.Cache;

public sealed class LabelReader(ICache cache)
{
    public Task<string> ReadAsync(string key) => cache.GetAsync(key);
}

缺失值与对象序列化由底层客户端行为共同决定,调用方应处理空结果。GetAndSet 不是分布式锁或去重保证,不能依赖它只执行一次业务副作用。网络和序列化异常需由消费端处理。

Program.cs 与缓存消费者

使用 Microsoft.NET.Sdk.Web,目标为本页列出的 .NET 8/9/10。宿主从外部配置提供 RedisSettings;不要把连接凭据写入代码。以下是完整的注册与调用关系,启动后调用端点才会进行缓存 I/O。

csharp
using Fast.Cache;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCache();
builder.Services.AddScoped<CatalogCache>();
var app = builder.Build();
app.MapGet("/catalog/{id:int}", (int id, CatalogCache cache) => cache.ReadAsync(id));
app.Run();

public sealed record CatalogItem(int Id, string Name);

public sealed class CatalogCache(ICache cache)
{
    public Task<CatalogItem> ReadAsync(int id) => cache.GetAndSetAsync(
        $"catalog:{id}", TimeSpan.FromMinutes(5),
        () => Task.FromResult(new CatalogItem(id, "示例商品")));

    public Task<bool> ReplaceAsync(CatalogItem item) =>
        cache.SetAsync($"catalog:{item.Id}", item, TimeSpan.FromMinutes(5));

    public Task<long> InvalidateAsync(int id) => cache.DelAsync($"catalog:{id}");
}

GetAndSetAsync 的返回值是缓存中的对象或工厂结果;示例工厂为本地固定数据,实际应用可替换为读取服务。不要依赖它实现跨进程互斥或防止并发重复计算。SetAsync 返回成功标志,DelAsync 返回实际删除数量;删除不存在的键不等于异常。Redis、序列化与工厂异常可传播给调用方,此接口没有统一的取消令牌参数。

来源与验证

依据 ICache 完整重载选项。本轮未编译、未连接或写入 Redis。

委托配置、客户端切换与原子消费

列表回调的第一项配置默认 Redis,后续项必须为具有唯一 ServiceNameRedisServiceSettingsOptions;它们共同绑定到实际消费的 IOptionsMonitor<RedisSettingsOptions>。空列表、重复名称和无名称附加项会明确失败。该调整没有连接或写入 Redis 的测试副作用。

配置变化时先创建新客户端,再原子发布不可变快照。新建失败保留旧客户端,并记录不含连接信息的诊断;一次缓存操作始终使用同一个客户端和 Prefix。公开 Client 是借用引用,不由调用方 Dispose。由于无法追踪外部借用者,旧代客户端保留至缓存服务释放;频繁热更新可能保留多个连接池,不承诺无限热更新而无资源成本。

注册 Fast.Cache 同时提供 Redis 原子刷新消费存储器;这是专门的防重放能力,不意味着普通 GetAndSet 也具有分布式互斥。