如何在测试场景中禁用ASP.NET Core的FusionCache缓存?
ASP.NET Core 6中FusionCache分环境全局禁用缓存的最佳实践
以下是几种落地性强的方案,可根据项目实际情况选择:
方案1:基于环境配置动态调整全局缓存选项
通过配置文件或环境标识,直接修改FusionCache的默认缓存条目配置,强制所有缓存项立即过期,达到禁用效果。
- 在对应环境的配置文件(如
appsettings.Test.json)中添加开关:{ "CacheSettings": { "EnableGlobalCache": false } } - 在
Program.cs中读取配置并注册FusionCache:var builder = WebApplication.CreateBuilder(args); var enableCache = builder.Configuration.GetValue<bool>("CacheSettings:EnableGlobalCache", true); builder.Services.AddFusionCache() .WithDefaultEntryOptions(options => { if (!enableCache) { // 设置过期时间为0,强制不缓存任何内容 options.Duration = TimeSpan.Zero; options.AllowBackgroundRefresh = false; options.SkipCacheExceptions = true; } else { // 正常环境的默认缓存时长 options.Duration = TimeSpan.FromMinutes(10); } }); - 也可直接通过环境判断,无需额外配置:
builder.Services.AddFusionCache() .WithDefaultEntryOptions(options => { if (builder.Environment.IsStaging() || builder.Environment.IsEnvironment("Test")) { options.Duration = TimeSpan.Zero; } });
方案2:替换底层缓存实现为NullCache
通过替换FusionCache的底层存储实现为“空操作”缓存,让所有读写请求无实际效果,彻底禁用缓存功能。
- 定义空缓存实现:
public class NullCacheStorage : IFusionCacheStorage { public ValueTask<byte[]?> GetAsync(string key, CancellationToken token = default) => ValueTask.FromResult<byte[]?>(null); public ValueTask SetAsync(string key, byte[] value, FusionCacheEntryOptions options, CancellationToken token = default) => ValueTask.CompletedTask; public ValueTask RemoveAsync(string key, CancellationToken token = default) => ValueTask.CompletedTask; // 实现接口剩余方法,全部做空操作 public ValueTask ClearAsync(CancellationToken token = default) => ValueTask.CompletedTask; public ValueTask<int> CountAsync(CancellationToken token = default) => ValueTask.FromResult(0); public ValueTask<IEnumerable<string>> GetKeysAsync(string prefix, CancellationToken token = default) => ValueTask.FromResult(Enumerable.Empty<string>()); } - 在
Program.cs中根据环境注册存储:builder.Services.AddFusionCache() .WithStorageFactory(sp => { var env = sp.GetRequiredService<IWebHostEnvironment>(); return env.IsEnvironment("Test") ? new NullCacheStorage() : new FusionCacheMemoryStorage(); });
方案3:用装饰器包装FusionCache服务
通过装饰器模式包装IFusionCache接口,在禁用环境下直接跳过缓存逻辑,调用原始业务方法。
- 实现装饰器类:
public class FusionCacheDisablingDecorator : IFusionCache { private readonly IFusionCache _innerCache; private readonly IWebHostEnvironment _env; public FusionCacheDisablingDecorator(IFusionCache innerCache, IWebHostEnvironment env) { _innerCache = innerCache; _env = env; } // 以核心方法GetOrSetAsync为例,其他方法同理处理 public async ValueTask<T> GetOrSetAsync<T>(string key, Func<ValueTask<T>> factory, FusionCacheEntryOptions? options = null, CancellationToken token = default) { if (_env.IsEnvironment("Test")) { // 禁用缓存时直接执行工厂方法,不走缓存 return await factory(); } return await _innerCache.GetOrSetAsync(key, factory, options, token); } // 实现IFusionCache接口的所有剩余方法,根据环境决定是否转发到内部缓存 } - 在
Program.cs中注册装饰器:builder.Services.AddFusionCache(); // 替换IFusionCache服务为装饰器 builder.Services.Decorate<IFusionCache, FusionCacheDisablingDecorator>();
注意事项
- 禁用缓存时,建议关闭FusionCache的后台刷新、分布式缓存同步等附加功能,减少不必要的资源消耗。
- 若项目使用分布式缓存(如Redis),需确保禁用环境下不连接分布式缓存服务,避免无效网络请求。
- 可结合CI/CD流程中的环境变量控制缓存开关,比如设置
ENABLE_CACHE=false,比配置文件更灵活。
内容的提问来源于stack exchange,提问作者Søren
相关产品推荐
相关产品推荐

