zoukankan      html  css  js  c++  java
  • 基于Asp.net Core 3.1实现的Redis及MemoryCache缓存助手CacheHelper

    这几天在面试,这个关于Redis缓存的博客一直没空写,今天总算有点时间了。

    从很久很久之前,我就一直想学Redis了,反正看到各大招聘网上都要求Redis,不学就太落后了。

    一开始我是按微软官网文档那样配置的,然后发现这也太简单了,不止配置简单,连使用都这么简单,简单得有点过分。如下图所示,它是基于IDistributedCache接口注入的

    这么简单,怎么玩,我连判断某个key值存不存在都没办法。

    当然了。绝对不是这么简单的。更高级的用法如下,要引入Microsoft.Extensions.Caching.StackExchangeRedis包

    ConnectionMultiplexer connection = ConnectionMultiplexer.Connect("127.0.0.1:6379");
    IDatabase cache = connection.GetDatabase(0);
    cache.HashSet("key", "hashKey", "value");
    cache.SetAdd("key2", "value");

    那要怎么用在系统里呢,当然直接使用IDatabase也可以,但不够优雅,而且我还想通过配置文件,来决定是否启用Redis,如果不启用的话,就使用MemoryCache。非常好。想法有了。

    先定义一个接口ICacheHelper,这是用来注入的接口,我暂时只定义了string类型跟hash类型的缓存方法

    public interface ICacheHelper
    {
        bool Exists(string key);
    
        void Set<T>(string key, T value);
    
        T Get<T>(string key);
    
        void Delete(string key);
    
    
        void Expire(string key, DateTime dateTime);
        void Expire(string key, TimeSpan timeSpan);
    
        void HashSet(string key, string hashKey, object hashValue);
        T HashGet<T>(string key, string hashKey);
    
        bool HashExists(string key, string hashKey);
    
        void HashDelete(string key, string hashKey);
    }

    然后用Redis实现这个接口,RedisCacheHelper类

    /// <summary>
    /// Redis助手
    /// </summary>
    public class RedisCacheHelper : ICacheHelper
    {
        public IDatabase _cache;
    
        private ConnectionMultiplexer _connection;
    
        private readonly string _instance;
        public RedisCacheHelper(RedisCacheOptions options, int database = 0)
        {
            _connection = ConnectionMultiplexer.Connect(options.Configuration);
            _cache = _connection.GetDatabase(database);
            _instance = options.InstanceName;
        }
    
        public bool Exists(string key)
        {
            return _cache.KeyExists(_instance + key);
        }
    
        public void Set<T>(string key, T value)
        {
            _cache.StringSet(_instance + key, CommonHelper.ObjectToJsonString(value));
        }
    
        public T Get<T>(string key)
        {
            return CommonHelper.JsonStringToObject<T>(_cache.StringGet(_instance + key));
        }
    
        public void Delete(string key)
        {
            _cache.KeyDelete(_instance + key);
        }
    
        public void Expire(string key, DateTime dateTime)
        {
            _cache.KeyExpire(_instance + key, dateTime);
        }
        public void Expire(string key, TimeSpan timeSpan)
        {
            _cache.KeyExpire(_instance + key, timeSpan);
        }
        public void HashSet(string key, string hashKey, object hashValue)
        {
            string value = CommonHelper.ObjectToJsonString(hashValue);
            _cache.HashSet(_instance + key, hashKey, value);
        }
    
        public T HashGet<T>(string key, string hashKey)
        {
            var value = _cache.HashGet(_instance + key, hashKey);
            return CommonHelper.JsonStringToObject<T>(value);
        }
    
        public object HashGet(string key, string hashKey, Type type)
        {
            var value = _cache.HashGet(_instance + key, hashKey);
            return CommonHelper.JsonStringToObject(value, type);
        }
    
        public bool HashExists(string key, string hashKey)
        {
            return _cache.HashExists(_instance + key, hashKey);
        }
    
        public void HashDelete(string key, string hashKey)
        {
            _cache.HashDelete(_instance + key, hashKey);
        }
    }

    再用MemoryCache实现接口,MemoryCacheHelper类

    /// <summary>
    /// 缓存助手
    /// </summary>
    public class MemoryCacheHelper : ICacheHelper
    {
        private readonly IMemoryCache _cache;
        public MemoryCacheHelper(IMemoryCache cache)
        {
            _cache = cache;
        }
    
        public bool Exists(string key)
        {
            return _cache.TryGetValue(key, out _);
        }
    
        public T Get<T>(string key)
        {
            return _cache.Get<T>(key);
        }
    
        public void Delete(string key)
        {
            _cache.Remove(key);
        }
    
        public void Set<T>(string key, T value)
        {
            _cache.Set(key, value);
        }
        public void Expire(string key, DateTime dateTime)
        {
            var value = _cache.Get(key);
            _cache.Set(key, value, dateTime);
        }
    
        public void Expire(string key, TimeSpan timeSpan)
        {
            var value = _cache.Get(key);
            _cache.Set(key, value, timeSpan);
        }
        public void HashSet(string key, string hashKey, object hashValue)
        {
            var hash = _cache.Get<Dictionary<string, object>>(key);
            if (hash.ContainsKey(hashKey))
            {
                hash[key] = hashValue;
            }
            else
            {
                hash.Add(hashKey, hashValue);
            }
            _cache.Set<Dictionary<string, object>>(key, hash);
        }
    
        public T HashGet<T>(string key, string hashKey)
        {
            var hash = _cache.Get<Dictionary<string, object>>(key);
            if (hash.ContainsKey(hashKey))
            {
                return (T)hash[hashKey];
            }
            else
            {
                return default(T);
            }
        }
    
        public bool HashExists(string key, string hashKey)
        {
            var hash = _cache.Get<Dictionary<string, object>>(key);
            return hash.ContainsKey(hashKey);
        }
    
    
    
        public void HashDelete(string key, string hashKey)
        {
            var hash = _cache.Get<Dictionary<string, object>>(key);
            if (hash.ContainsKey(hashKey))
            {
                hash.Remove(hashKey);
            }
        }
    }

    实现类都有了,那现在就来实现根据配置值来决定是否使用Redis还是MemoryCache,先在appsettings.json里添加这个配置值,当Enable为false时,就不启用Redis,使用MemoryCache,Connection是Redis的连接字符串,InstanceName是缓存的前缀,Database是使用哪个数据库

    "Redis": {
        "Enable": true,
        "Connection": "127.0.0.1:6379",
        "InstanceName": "LessSharp:",
        "Database": 0
      }

    再定义一个选项类 RedisOption

    public class RedisOption
    {
        public bool Enable { get; set; }        
        public string Connection { get; set; }
        public string InstanceName { get; set; }
        public int Database { get; set; }
    }

    然后在Startup.cs类里的ConfigureServices里根据配置值进行注入

    var RedisConfiguration = Configuration.GetSection("Redis");
    services.Configure<RedisOption>(RedisConfiguration);
    RedisOption redisOption = RedisConfiguration.Get<RedisOption>();
    if (redisOption != null && redisOption.Enable)
    {
        var options = new RedisCacheOptions
        {
            InstanceName = redisOption.InstanceName,
            Configuration = redisOption.Connection
         };
         var redis = new RedisCacheHelper(options, redisOption.Database);
         services.AddSingleton(redis);
         services.AddSingleton<ICacheHelper>(redis);
    }
    else
    {
          services.AddMemoryCache();
          services.AddScoped<ICacheHelper, MemoryCacheHelper>();
    }

    OK,测试后完美

  • 相关阅读:
    nios sgdma(Scatter-Gather dma)示例
    关于nios 中printf 的问题
    Nios II 系统时钟timestamp的应用
    DMA在FPGA的应用之我见
    PIO Core
    VGA接口时序约束
    时序分析,重中之重,柳暗花明又一村 搞定美女了问题
    深入浅出VGA和DVI接口
    基于FPGA的VGA可移植模块终极设计
    理解FPGA中的RAM、ROM和CAM;ROM、RAM、DRAM、SRAM、FLASH
  • 原文地址:https://www.cnblogs.com/caijt/p/13455471.html
Copyright © 2011-2022 走看看