Based on the .Net Core API framework structures (3)

5, by adding cache support

   We hope to increase caching support for the project, we chose Redis as cache database.

   First of all, we are in Services to add a cache interface class directory ICacheService :

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

 

namespace ChainStoreAPI.Services

{

    public interface ICacheService

    {

        /// <summary>

        /// verify the existence of the cache entry

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        bool Exists(string key);

 

        /// <summary>

        /// verify the existence of the cache entry (asynchronous)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        Task<bool> ExistsAsync(string key);

 

        /// <summary>

        /// add cache

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <returns></returns>

        bool Add(string key, object value);

 

        /// <summary>

        /// add the cache (asynchronous)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <returns></returns>

        Task<bool> AddAsync(string key, object value);

 

        /// <summary>

        /// add cache

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <param name="expiressAbsoulte">绝对过期时长</param>

        /// <returns></returns>

        bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte);

 

        /// <summary>

        /// 添加缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <param name="expiressAbsoulte">绝对过期时长</param>

        /// <returns></returns>

        Task<bool> AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte);

 

        /// <summary>

        /// 添加缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <param name="expiresIn">缓存时长</param>

        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <returns></returns>

        bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false);

 

        /// <summary>

        /// 添加缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <param name="expiresIn">缓存时长</param>

        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <returns></returns>

        Task<bool> AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false);

 

        /// <summary>

        /// 删除缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        bool Remove(string key);

 

        /// <summary>

        /// 删除缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        Task<bool> RemoveAsync(string key);

 

        /// <summary>

        /// 批量删除缓存

        /// </summary>

        /// <param name="key">缓存Key集合</param>

        /// <returns></returns>

        void RemoveAll(IEnumerable<string> keys);

 

        /// <summary>

        /// 批量删除缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key集合</param>

        /// <returns></returns>

        Task RemoveAllAsync(IEnumerable<string> keys);

 

        /// <summary>

        /// 获取缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        T Get<T>(string key) where T : class;

 

        /// <summary>

        /// 获取缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        Task<T> GetAsync<T>(string key) where T : class;

 

        /// <summary>

        /// 获取缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        object Get(string key);

 

        /// <summary>

        /// 获取缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        Task<object> GetAsync(string key);

 

        /// <summary>

        /// 获取缓存集合

        /// </summary>

        /// <param name="keys">缓存Key集合</param>

        /// <returns></returns>

        IDictionary<string, object> GetAll(IEnumerable<string> keys);

 

        /// <summary>

        /// 获取缓存集合(异步方式)

        /// </summary>

        /// <param name="keys">缓存Key集合</param>

        /// <returns></returns>

        Task<IDictionary<string, object>> GetAllAsync(IEnumerable<string> keys);

 

        /// <summary>

        /// 修改缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <returns></returns>

        bool Replace(string key, object value);

 

        /// <summary>

        /// 修改缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <returns></returns>

        Task<bool> ReplaceAsync(string key, object value);

 

        /// <summary>

        /// 修改缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <param name="expiressAbsoulte">绝对过期时长</param>

        /// <returns></returns>

        bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte);

 

        /// <summary>

        /// 修改缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <param name="expiressAbsoulte">绝对过期时长</param>

        /// <returns></returns>

        Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte);

 

        /// <summary>

        /// 修改缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <param name="expiresIn">缓存时长</param>

        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <returns></returns>

        bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false);

 

        /// <summary>

        /// 修改缓存(异步方式)

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <param name="expiresIn">缓存时长</param>

        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <returns></returns>

        Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false);

    }

}

 

然后,在增加实现类之前,先引入Redis的依赖项:

 

 

选择Microsoft.Extensions.Caching.Redis,版本选择2.1.2,安装一下。

 

Services\Impl目录增加Redis的缓存实现类RedisCacheService

using Microsoft.Extensions.Caching.Redis;

using Newtonsoft.Json;

using StackExchange.Redis;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ChainStoreAPI.Services.Impl

{

    public class RedisCacheService : ICacheService

    {

        protected IDatabase _cache;

 

        private ConnectionMultiplexer _connection;

 

        private readonly string _instance;

 

        /// <summary>

        /// 构造函数

        /// </summary>

        /// <param name="options"></param>

        /// <param name="database"></param>

        public RedisCacheService(RedisCacheOptions options, int database = 0)

        {

            _connection = ConnectionMultiplexer.Connect(options.Configuration);

            _cache = _connection.GetDatabase(database);

            _instance = options.InstanceName;

        }

 

        /// <summary>

        /// 为Key添加实例名

        /// </summary>

        /// <param name="key"></param>

        /// <returns></returns>

        public string GetKeyForRedis(string key)

        {

            return _instance + ":" + key;

        }

 

        #region 验证缓存项是否存在

        /// <summary>

        /// 验证缓存项是否存在

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        public bool Exists(string key)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

            return _cache.KeyExists(GetKeyForRedis(key));

        }

 

        public async Task<bool> ExistsAsync(string key)

        {

            bool result = await Task.Run(() => Exists(key));

            return result;

        }

        #endregion

 

        #region 添加缓存

        /// <summary>

        /// 添加缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <returns></returns>

        public bool Add(string key, object value)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

            return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)));

        }

 

        /// <summary>

        /// 添加缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param>

        /// <param name="expiressAbsoulte">绝对过期时长</param>

        /// <returns></returns>

        public bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

            return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)), expiressAbsoulte);

        }

 

        /// <summary>

        /// 添加缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">缓存Value</param>

        /// <param name="expiresIn">缓存时长</param>

        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param>

        /// <returns></returns>

        public bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

 

            return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)), expiresIn);

        }

 

        public async Task<bool> AddAsync(string key, object value)

        {

            bool result = await Task.Run(() => Add(key, value));

            return result;

        }

 

        public async Task<bool> AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)

        {

            bool result = await Task.Run(() => Add(key, value, expiresSliding, expiressAbsoulte));

            return result;

        }

 

        public async Task<bool> AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false)

        {

            bool result = await Task.Run(() => Add(key, value, expiresIn, isSliding));

            return result;

        }

        #endregion

 

        #region 删除缓存

        /// <summary>

        /// 删除缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        public bool Remove(string key)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

            return _cache.KeyDelete(GetKeyForRedis(key));

        }

 

        /// <summary>

        /// 批量删除缓存

        /// </summary>

        /// <param name="key">缓存Key集合</param>

        /// <returns></returns>

        public void RemoveAll(IEnumerable<string> keys)

        {

            if (keys == null)

            {

                throw new ArgumentNullException(nameof(keys));

            }

 

            keys.ToList().ForEach(item => Remove(item));

        }

 

        public async Task<bool> RemoveAsync(string key)

        {

            bool result = await Task.Run(() => Remove(key));

            return result;

        }

 

        public async Task RemoveAllAsync(IEnumerable<string> keys)

        {

            await Task.Run(() => RemoveAll(keys));

        }

        #endregion

 

        #region 获取缓存

        /// <summary>

        /// 获取缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        public T Get<T>(string key) where T : class

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

 

            var value = _cache.StringGet(GetKeyForRedis(key));

            if (!value.HasValue)

            {

                return default(T);

            }

 

            return JsonConvert.DeserializeObject<T>(value);

        }

 

        /// <summary>

        /// 获取缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <returns></returns>

        public object Get(string key)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

 

            var value = _cache.StringGet(GetKeyForRedis(key));

            if (!value.HasValue)

            {

                return null;

            }

 

            return JsonConvert.DeserializeObject(value);

        }

 

        /// <summary>

        /// 获取缓存集合

        /// </summary>

        /// <param name="keys">缓存Key集合</param>

        /// <returns></returns>

        public IDictionary<string, object> GetAll(IEnumerable<string> keys)

        {

            if (keys == null)

            {

                throw new ArgumentNullException(nameof(keys));

            }

 

            var dict = new Dictionary<string, object>();

            keys.ToList().ForEach(item => dict.Add(item, Get(GetKeyForRedis(item))));

 

            return dict;

        }

 

        public async Task<T> GetAsync<T>(string key) where T : class

        {

            T result = await Task.Run(() => Get(key)) as T;

            return result;

        }

 

        public async Task<object> GetAsync(string key)

        {

            object result = await Task.Run(() => Get(key));

            return result;

        }

 

        public async Task<IDictionary<string, object>> GetAllAsync(IEnumerable<string> keys)

        {

            IDictionary<string, object> result = await Task.Run(() => GetAll(keys));

            return result;

        }

        #endregion

 

        #region 修改缓存

        /// <summary>

        /// 修改缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <returns></returns>

        public bool Replace(string key, object value)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

 

            if (Exists(key))

                if (!Remove(key))

                    return false;

 

            return Add(key, value);

        }

 

        /// <summary>

        /// 修改缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <param name="expiressAbsoulte">绝对过期时长</param>

        /// <returns></returns>

        public bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

 

            if (Exists(key))

                if (!Remove(key))

                    return false;

 

            return Add(key, value, expiresSliding, expiressAbsoulte);

        }

 

        /// <summary>

        /// 修改缓存

        /// </summary>

        /// <param name="key">缓存Key</param>

        /// <param name="value">新的缓存Value</param>

        /// <param name="expiresIn">缓存时长</param>

        /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>

        /// <returns></returns>

        public bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false)

        {

            if (key == null)

            {

                throw new ArgumentNullException(nameof(key));

            }

 

            if (Exists(key))

                if (!Remove(key)) return false;

 

            return Add(key, value, expiresIn, isSliding);

        }

 

        public async Task<bool> ReplaceAsync(string key, object value)

        {

            bool result = await Task.Run(() => Replace(key, value));

            return result;

        }

 

        public async Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)

        {

            bool result = await Task.Run(() => Replace(key, value, expiresSliding, expiressAbsoulte));

            return result;

        }

 

        public async Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false)

        {

            bool result = await Task.Run(() => Replace(key, value, expiresIn, isSliding));

            return result;

        }

        #endregion

 

        /// <summary>

        /// 释放

        /// </summary>

        public void Dispose()

        {

            if (_connection != null)

                _connection.Dispose();

            GC.SuppressFinalize(this);

        }

    }

}

 

在配置文件appsettings.json中加入Redis的链接字符串:

 

 

"RedisConnectionString": "127.0.0.1:6379"

 

然后打开Startup.cs,引入缓存服务类:

 

 

 

当然,现在我们需要安装好Redis并启动:

 

 

运行run.bat即可:

 

 

 

我们将控制器TestController.cs重命名为MemberController.cs

 

 

再新增测试控制器,将来我们的测试代码都在这里面实现:

 

 

 

 

我们只保留Get方法,其他全删除:

 

 

 

修改BaseController,加入缓存支持:

 

 

 

这样,我们就可以在所有继承BaseController的控制器中使用缓存了。

修改MemberControllerTestController的构造函数:

 

 

 

 

下面我们在测试控制器中写代码测试一下缓存的写入和读取:

// GET: api/Test

        [HttpGet]

        public ResultInfo Get()

        {

            cache.Add("test", "这是一个测试字符串");

            string value = cache.Get<string>("test");

 

            return new ResultInfo() { Code = "0", Message = "成功", Data = value };

        }

 

运行看一下效果:

 

 

打开RedisDesktopManager看一下Redis数据库中是否写入:

 

 

Guess you like

Origin www.cnblogs.com/yzqnet/p/10941575.html