1、前言
前一篇博客介绍了ASP.NET Core
中本地缓存MemoryCache
的使用方法。相较于本地缓存,分布式缓存更加适合大多数项目应用场景,下面就来介绍一下如何在ASP.NET Core
中对Redis
缓存进行相关操作。
2、分布式缓存接口——IDistributedCache
对于分布式缓存,微软提供了IDistributedCache
接口进行相关操作,该接口支持SQL Server
、NCache
、Redis
等多种缓存。其包含的方法如下所示:
虽然IDistributedCache
接口提供的方法较少,但对于简单的缓存操作完全够用。本文以Redis
为例,因此需要使用Nuget
引入如下程序包:
Microsoft.Extensions.Caching.StackExchangeRedis
引入Redis
相关组件后,需要在Startup.cs
中添加相关服务,代码如下:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace App
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// 添加Redis缓存服务
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "127.0.0.1:6379";
options.InstanceName = "App:";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
2.1、创建缓存
创建缓存的代码如下:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
private readonly IDistributedCache cache;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="cache"></param>
public HomeController(IDistributedCache cache)
{
this.cache = cache;
}
/// <summary>
/// 设置缓存
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult<string> SetCache()
{
cache.SetString("UserName", "admin");
cache.SetString("Password", "12345");
return "设置缓存成功";
}
}
}
运行程序,发现Redis
中已经创建了对应缓存,如下图所示:
2.2、读取缓存
读取缓存的代码如下:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
private readonly IDistributedCache cache;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="cache"></param>
public HomeController(IDistributedCache cache)
{
this.cache = cache;
}
/// <summary>
/// 获取缓存
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult<string> GetCache()
{
string userName = cache.GetString("UserName");
string password = cache.GetString("Password");
return $"用户名:{userName}\n密码:{password}";
}
}
}
运行程序,发现能够读取对应缓存,如下图所示:
2.3、删除缓存
删除缓存的代码如下:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
private readonly IDistributedCache cache;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="cache"></param>
public HomeController(IDistributedCache cache)
{
this.cache = cache;
}
/// <summary>
/// 删除缓存
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult<string> RemoveCache()
{
cache.Remove("UserName");
cache.Remove("Password");
return "删除缓存成功";
}
}
}
运行程序,发现Redis
中已经删除了对应缓存,如下图所示:
3、自定义缓存帮助类——RedisCacheHelper
3.1、添加Redis配置参数
在appsettings.json
文件中添加配置参数RedisSettings
,其中:Connection
表示连接字符串,InstanceName
表示实例名称,Database
表示Redis
中的数据库编号,代码如下所示:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"RedisSettings": {
"Connection": "127.0.0.1:6379",
"InstanceName": "App:",
"Database": 2
}
}
3.2、添加实体类映射配置参数
创建一个实体类RedisSettings.cs
,该类用以映射配置参数,代码如下所示:
namespace App
{
public class RedisSettings
{
/// <summary>
/// 连接字符串
/// </summary>
public string Connection { get; set; }
/// <summary>
/// 实例名称
/// </summary>
public string InstanceName { get; set; }
/// <summary>
/// 数据库编号
/// </summary>
public int Database { get; set; }
}
}
3.3、添加Redis帮助类
创建IRedisCacheHelper
接口,代码如下所示:
using System.Collections.Generic;
namespace App
{
public interface IRedisCacheHelper
{
/// <summary>
/// 获取缓存
/// </summary>
/// <typeparam name="TValue">缓存值类型</typeparam>
/// <param name="key">键</param>
/// <returns>缓存值</returns>
TValue Get<TValue>(string key);
/// <summary>
/// 获取缓存
/// </summary>
/// <typeparam name="TValue">缓存值类型</typeparam>
/// <param name="keys">键集合</param>
/// <returns>缓存值集合</returns>
List<TValue> Get<TValue>(List<string> keys);
/// <summary>
/// 设置缓存
/// </summary>
/// <typeparam name="TValue">缓存值类型</typeparam>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="expires">过期时间</param>
/// <param name="isSliding">是否滑动过期</param>
/// <returns>是否成功</returns>
bool Set<TValue>(string key, TValue value, int expires = 0, bool isSliding = false);
/// <summary>
/// 判断缓存是否存在
/// </summary>
/// <param name="key">键</param>
/// <returns>是否存在</returns>
bool Exists(string key);
/// <summary>
/// 移除缓存
/// </summary>
/// <param name="key">键</param>
/// <returns>是否成功</returns>
bool Remove(string key);
/// <summary>
/// 移除缓存
/// </summary>
/// <param name="keys">键集合</param>
/// <returns>是否成功</returns>
bool Remove(List<string> keys);
}
}
创建RedisCacheHelper
类实现IRedisCacheHelper
接口,这里的代码会把数据全部以JSON
的形式存入Redis
,因此需要引入Newtonsoft.Json
组件,代码如下所示:
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Newtonsoft.Json;
using StackExchange.Redis;
using System.Collections.Generic;
namespace App
{
public class RedisCacheHelper : IRedisCacheHelper
{
private readonly IDatabase database;
private readonly ConnectionMultiplexer connection;
private readonly string instanceName;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="options"></param>
/// <param name="database"></param>
public RedisCacheHelper(RedisCacheOptions options, int database = 0)
{
this.connection = ConnectionMultiplexer.Connect(options.Configuration);
this.database = connection.GetDatabase(database);
this.instanceName = options.InstanceName;
}
/// <summary>
/// 获取缓存
/// </summary>
/// <typeparam name="TValue">缓存值类型</typeparam>
/// <param name="key">键</param>
/// <returns>缓存值</returns>
public TValue Get<TValue>(string key)
{
string json = database.StringGet(instanceName + key);
return JsonConvert.DeserializeObject<TValue>(json);
}
/// <summary>
/// 获取缓存
/// </summary>
/// <typeparam name="TValue">缓存值类型</typeparam>
/// <param name="keys">键集合</param>
/// <returns>缓存值集合</returns>
public List<TValue> Get<TValue>(List<string> keys)
{
List<TValue> list = new List<TValue>();
foreach (string key in keys)
{
TValue value = JsonConvert.DeserializeObject<TValue>(database.StringGet(instanceName + key));
list.Add(value);
}
return list;
}
/// <summary>
/// 设置缓存
/// </summary>
/// <typeparam name="TValue">缓存值类型</typeparam>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="expires">过期时间</param>
/// <param name="isSliding">是否滑动过期</param>
/// <returns>是否成功</returns>
public bool Set<TValue>(string key, TValue value, int expires = 0, bool isSliding = false)
{
return database.StringSet(instanceName + key, JsonConvert.SerializeObject(value));
}
/// <summary>
/// 判断缓存是否存在
/// </summary>
/// <param name="key">键</param>
/// <returns>是否存在</returns>
public bool Exists(string key)
{
return database.KeyExists(instanceName + key);
}
/// <summary>
/// 移除缓存
/// </summary>
/// <param name="key">键</param>
/// <returns>是否成功</returns>
public bool Remove(string key)
{
try
{
database.KeyDelete(instanceName + key);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 移除缓存
/// </summary>
/// <param name="keys">键集合</param>
/// <returns>是否成功</returns>
public bool Remove(List<string> keys)
{
try
{
foreach (string key in keys)
{
database.KeyDelete(instanceName + key);
}
return true;
}
catch
{
return false;
}
}
}
}
3.4、注册Redis帮助类
配置参数、实体类、帮助类已经定义完毕,接下来就是在Startup.cs
文件中注册了,代码如下:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace App
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// 获取实体类
var settings = Configuration.GetSection("RedisSettings").Get<RedisSettings>();
// 设置配置参数
var options = new RedisCacheOptions
{
InstanceName = settings.InstanceName,
Configuration = settings.Connection
};
// 实例化帮助类
var helper = new RedisCacheHelper(options, settings.Database);
services.AddSingleton<IRedisCacheHelper>(helper);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
3.5、Controller中注入Redis帮助类
在HomeController
中添加如下代码:
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HomeController : ControllerBase
{
private readonly IRedisCacheHelper helper;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="helper"></param>
public HomeController(IRedisCacheHelper helper)
{
this.helper = helper;
}
/// <summary>
/// 设置缓存
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult<string> SetCache()
{
helper.Set<string>("UserName", "admin");
helper.Set<string>("Password", "12345");
return "设置缓存成功";
}
/// <summary>
/// 获取缓存
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult<string> GetCache()
{
return helper.Get<string>("UserName") + "\n" +
helper.Get<string>("Password");
}
/// <summary>
/// 删除缓存
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult<string> RemoveCache()
{
if (helper.Exists("UserName"))
{
helper.Remove("UserName");
}
if (helper.Exists("Password"))
{
helper.Remove("Password");
}
return "删除缓存成功";
}
}
}
当执行SetCache
方法时,运行结果如下所示,可以发现在编号为2
的数据库中添加了两个缓存:
当执行GetCache
方法时,运行结果如下所示,可以发现能够正确读取对应缓存:
当执行RemoveCache
方法时,运行结果如下所示,可以发现2
号数据库已经清除了对应缓存:
4、结语
本文主要介绍了ASP.NET Core
中Redis
缓存的简单使用方法,在实际开发中Redis
的应用相当广泛,有兴趣的同志可自行深入研究其用法。