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

这么简单,怎么玩,我连判断某个key值存不存在都没办法。
当然了。绝对不是这么简单的。更高级的用法如下,要引入Microsoft.Extensions.Caching.StackExchangeRedis包
1 2 3 4
| 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类型的缓存方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
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类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
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是使用哪个数据库
1 2 3 4 5 6
| "Redis": { "Enable": true, "Connection": "127.0.0.1:6379", "InstanceName": "LessSharp:", "Database": 0 }
|
再定义一个选项类 RedisOption
1 2 3 4 5 6 7
| 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里根据配置值进行注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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,测试后完美