需求
最近项目中要加页面缓存功能,因为网站内存有限,页面只能存在硬盘中,ASP.NET Core提供了ResponseCache中间件,但是只支持内存缓存,我们需要将缓存存在页面文件中
并且如果产品、系列在后台被修改,需要尽可能实时的修改页面
所以需要通过ResponseCache中间件源码查看如何扩展
源码
ResponseCachingMiddleware构造函数
internal ResponseCachingMiddleware(
RequestDelegate next,
IOptions<ResponseCachingOptions> options,
ILoggerFactory loggerFactory,
IResponseCachingPolicyProvider policyProvider,
IResponseCache cache,
IResponseCachingKeyProvider keyProvider)
{
_next = next;
_options = options.Value;
_logger = loggerFactory.CreateLogger<ResponseCachingMiddleware>();
_policyProvider = policyProvider;
_cache = cache;
_keyProvider = keyProvider;
}
IResponseCache:提供缓存的读取和写入,框架中只提供了一个内存缓存的实现类,如果需要将缓存写入其他位置,可实现此接口
internal interface IResponseCache
{
IResponseCacheEntry? Get(string key);
void Set(string key, IResponseCacheEntry entry, TimeSpan validFor);
}
看到这就知道,如果需要使用其他方式缓存接口内容,需要实现此接口
MemoryResponseCache
IResponseCache接口的实现类
internal class MemoryResponseCache : IResponseCache
{
private readonly IMemoryCache _cache;
internal MemoryResponseCache(IMemoryCache cache)
{
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
}
public IResponseCacheEntry? Get(string key)
{
var entry = _cache.Get(key);
if (entry is MemoryCachedResponse memoryCachedResponse)
{
return new CachedResponse
{
Created = memoryCachedResponse.Created,
StatusCode = memoryCachedResponse.StatusCode,
Headers = memoryCachedResponse.Headers,
Body = memoryCachedResponse.Body
};
}
else
{
return entry as IResponseCacheEntry;
}
}
public void Set(string key, IResponseCacheEntry entry, TimeSpan validFor)
{
if (entry is CachedResponse cachedResponse)
{
_cache.Set(
key,
new MemoryCachedResponse
{
Created = cachedResponse.Created,
StatusCode = cachedResponse.StatusCode,
Headers = cachedResponse.Headers,
Body = cachedResponse.Body
},
new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = validFor,
Size = CacheEntryHelpers.EstimateCachedResponseSize(cachedResponse)
});
}
else
{
_cache.Set(
key,
entry,
new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = validFor,
Size = CacheEntryHelpers.EstimateCachedVaryByRulesySize(entry as CachedVaryByRules)
});
}
}
}
IResponseCachingKeyProvider
缓存key提供器,后台修改产品数据,我需要找到对应的页面文件,所以缓存key也必须由我生成,比如以下格式:product_001_参数哈希
IResponseCachingPolicyProvider、ResponseCachingPolicyProvider
缓存策略,内部几个方法用来判断是否应该使用缓存
比如:必须是get、head请求,且Header中没有Authorization,才取缓存
ResponseCachingStream
Response.Body流的装饰器