基于Asp.net Core3.1实现Redis及MemoryCache缓存助手CacheHelper

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

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

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

  

基于Asp.net Core3.1实现Redis及MemoryCache缓存助手CacheHelper

  这么简单,怎么玩,我连判断某个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(string key, T value);

  T Get(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(string key, string hashKey); bool HashExists(string key, string hashKey); void HashDelete(string key, string hashKey);

  }

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

  

/// 

  /// Redis助手 ///

  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(string key, T value)

  {

  _cache.StringSet(_instance + key, CommonHelper.ObjectToJsonString(value));

  } public T Get(string key)

  { return CommonHelper.JsonStringToObject(_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(string key, string hashKey)

  { var value=_cache.HashGet(_instance + key, hashKey); return CommonHelper.JsonStringToObject(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类

  

/// 

  /// 缓存助手 ///

  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(string key)

  { return _cache.Get(key);

  } public void Delete(string key)

  {

  _cache.Remove(key);

  } public void Set(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>(key); if (hash.ContainsKey(hashKey))

  {

  hash[key]=hashValue;

  } else {

  hash.Add(hashKey, hashValue);

  }

  _cache.Set>(key, hash);

  } public T HashGet(string key, string hashKey)

  { var hash=_cache.Get>(key); if (hash.ContainsKey(hashKey))

  { return (T)hash[hashKey];

  } else { return default(T);

  }

  } public bool HashExists(string key, string hashKey)

  { var hash=_cache.Get>(key); return hash.ContainsKey(hashKey);

  } public void HashDelete(string key, string hashKey)

  { var hash=_cache.Get>(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(RedisConfiguration);

  RedisOption redisOption=RedisConfiguration.Get(); 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(redis);

  } else {

  services.AddMemoryCache();

  services.AddScoped();

  }

  OK,测试后完美

上一篇:ASP.NET 运行状况监视的日志记录错误详细信息 (C#)


下一篇:初学TypeScript之基本数据类型