ASP.NET Core 3.1系列(14)——分布式缓存Redis的使用

1、前言

前一篇博客介绍了ASP.NET Core中本地缓存MemoryCache的使用方法。相较于本地缓存,分布式缓存更加适合大多数项目应用场景,下面就来介绍一下如何在ASP.NET Core中对Redis缓存进行相关操作。

2、分布式缓存接口——IDistributedCache

对于分布式缓存,微软提供了IDistributedCache接口进行相关操作,该接口支持SQL ServerNCacheRedis等多种缓存。其包含的方法如下所示:
在这里插入图片描述
虽然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 CoreRedis缓存的简单使用方法,在实际开发中Redis的应用相当广泛,有兴趣的同志可自行深入研究其用法。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值