分布式缓存\appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
分布式缓存\appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
分布式缓存\DistributedCacheHelper.cs
using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Zack.ASPNETCore
{
public class DistributedCacheHelper : IDistributedCacheHelper
{
private readonly IDistributedCache distCache;
public DistributedCacheHelper(IDistributedCache distCache)
{
this.distCache = distCache;
}
private static DistributedCacheEntryOptions CreateOptions(int baseExpireSeconds)
{
//过期时间.Random.Shared 是.NET6新增的
double sec = Random.Shared.Next(baseExpireSeconds, baseExpireSeconds * 2);
TimeSpan expiration = TimeSpan.FromSeconds(sec);
DistributedCacheEntryOptions options = new DistributedCacheEntryOptions();
options.AbsoluteExpirationRelativeToNow = expiration;
return options;
}
public TResult? GetOrCreate<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, TResult?> valueFactory, int expireSeconds = 60)
{
string jsonStr = distCache.GetString(cacheKey);
//缓存中不存在
if (string.IsNullOrEmpty(jsonStr))
{
var options = CreateOptions(expireSeconds);
TResult? result = valueFactory(options);//如果数据源中也没有查到,可能会返回null
//null会被json序列化为字符串"null",所以可以防范“缓存穿透”
string jsonOfResult = JsonSerializer.Serialize(result,
typeof(TResult));
distCache.SetString(cacheKey, jsonOfResult, options);
return result;
}
else
{
//"null"会被反序列化为null
//TResult如果是引用类型,就有为null的可能性;如果TResult是值类型
//在写入的时候肯定写入的是0、1之类的值,反序列化出来不会是null
//所以如果obj这里为null,那么存进去的时候一定是引用类型
distCache.Refresh(cacheKey);//刷新,以便于滑动过期时间延期
return JsonSerializer.Deserialize<TResult>(jsonStr)!;
}
}
public async Task<TResult?> GetOrCreateAsync<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, Task<TResult?>> valueFactory, int expireSeconds = 60)
{
string jsonStr = await distCache.GetStringAsync(cacheKey);
if (string.IsNullOrEmpty(jsonStr))
{
var options = CreateOptions(expireSeconds);
TResult? result = await valueFactory(options);
string jsonOfResult = JsonSerializer.Serialize(result,typeof(TResult));
await distCache.SetStringAsync(cacheKey, jsonOfResult, options);
return result;
}
else
{
await distCache.RefreshAsync(cacheKey);
return JsonSerializer.Deserialize<TResult>(jsonStr)!;
}
}
public void Remove(string cacheKey)
{
distCache.Remove(cacheKey);
}
public Task RemoveAsync(string cacheKey)
{
return distCache.RemoveAsync(cacheKey);
}
}
}
分布式缓存\IDistributedCacheHelper.cs
using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Threading.Tasks;
namespace Zack.ASPNETCore
{
public interface IDistributedCacheHelper
{
TResult? GetOrCreate<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, TResult?> valueFactory, int expireSeconds = 60);
Task<TResult?> GetOrCreateAsync<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, Task<TResult?>> valueFactory, int expireSeconds = 60);
void Remove(string cacheKey);
Task RemoveAsync(string cacheKey);
}
}
分布式缓存\Program.cs
using Zack.ASPNETCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost:6379";
options.InstanceName = "pre_";
});
builder.Services.AddScoped<IDistributedCacheHelper, DistributedCacheHelper>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
分布式缓存\分布式缓存.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>
分布式缓存\Controllers\Test1Controller.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Zack.ASPNETCore;
namespace 分布式缓存.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
public class Test1Controller : ControllerBase
{
private readonly IDistributedCache distCache;
private readonly IDistributedCacheHelper helper;
public Test1Controller(IDistributedCache distCache, IDistributedCacheHelper helper)
{
this.distCache = distCache;
this.helper = helper;
}
[HttpGet]
public string Now()
{
string s = distCache.GetString("Now");
if (s == null)
{
s = DateTime.Now.ToString();
var opt = new DistributedCacheEntryOptions();
opt.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(180);
distCache.SetString("Now", s, opt);
}
return s;
}
[HttpGet]
public Task<string?> Now2()
{
return helper.GetOrCreateAsync<string>("Now2", async e => DateTime.Now.ToString());
}
}
}
标签:缓存,string,distCache,redis,cacheKey,dotnet,using,options
From: https://www.cnblogs.com/zhuoss/p/18014634