using Microsoft.Extensions.Caching.StackExchangeRedis;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Znyc.Cloudcar.Admin.Commons.Cache
{
///
/// Redis缓存操作
///
public class RedisCacheService : ICacheService
{
///
///
private readonly ConnectionMultiplexer _connection;
///
///
private readonly string _instance;
private readonly JsonSerializerOptions _jsonOptions;
///
///
protected IDatabase _cache;
///
///
///
///
///
public RedisCacheService(RedisCacheOptions options, JsonSerializerOptions jsonOptions, int database = 0)
{
_connection = ConnectionMultiplexer.Connect(options.Configuration);
_cache = _connection.GetDatabase(database);
_instance = options.InstanceName;
_jsonOptions = jsonOptions;
}
///
///
///
///
public string GetKeyForRedis(string key)
{
return _instance + key;
}
public void Dispose()
{
if (_connection != null)
{
_connection.Dispose();
}
GC.SuppressFinalize(this);
}
#region 验证缓存项是否存在
///
/// 验证缓存项是否存在
///
/// 缓存Key
///
public bool Exists(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyExists(GetKeyForRedis(key));
}
///
/// 验证缓存项是否存在
///
/// 缓存Key
///
public Task ExistsAsync(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyExistsAsync(GetKeyForRedis(key));
}
#endregion 验证缓存项是否存在
#region 添加缓存
///
/// 添加缓存
///
/// 缓存Key
/// 缓存Value
///
public bool Add(string key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSet(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)));
}
///
/// 添加缓存
///
/// 缓存Key
/// 缓存Value
/// 滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)
/// 绝对过期时长
///
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(JsonSerializer.Serialize(value, _jsonOptions)), expiressAbsoulte);
}
///
/// 添加缓存
///
/// 缓存Key
/// 缓存Value
/// 缓存时长
/// 是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)
///
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(JsonSerializer.Serialize(value, _jsonOptions)), expiresIn);
}
public Task AddAsync(string key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)));
}
public Task AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiressAbsoulte);
}
public Task AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiresIn);
}
public Task HashSetAsync(string key, string filed, object value)
{
return _cache.HashSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(filed, _jsonOptions)),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)));
}
#endregion 添加缓存
#region 删除缓存
///
/// 删除缓存
///
/// 缓存Key
///
public bool Remove(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyDelete(GetKeyForRedis(key));
}
///
/// 批量删除缓存
///
/// 缓存Key集合
///
public void RemoveAll(IEnumerable keys)
{
if (keys == null)
{
throw new ArgumentNullException(nameof(keys));
}
keys.ToList().ForEach(item => Remove(item));
}
///
///
///
///
public Task RemoveAsync(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyDeleteAsync(GetKeyForRedis(key));
}
public Task RemoveAllAsync(IEnumerable keys)
{
//if (keys == null)
//{
throw new ArgumentNullException(nameof(keys));
//}
//keys.ToList().ForEach(item => RemoveAsync(item));
}
///
/// 使用通配符找出所有的key然后逐个删除
///
/// 通配符
public virtual void RemoveByPattern(string pattern)
{
foreach (System.Net.EndPoint ep in _connection.GetEndPoints())
{
IServer server = _connection.GetServer(ep);
IEnumerable keys = server.Keys(pattern: "*" + pattern + "*", database: _cache.Database);
foreach (RedisKey key in keys)
{
_cache.KeyDelete(key);
}
}
}
///
/// 删除所有缓存
///
public void RemoveCacheAll()
{
RemoveByPattern("");
}
#endregion 删除缓存
#region 获取缓存
///
/// 获取缓存
///
/// 缓存Key
///
public T Get(string key) where T : class
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
RedisValue value = _cache.StringGet(GetKeyForRedis(key));
if (!value.HasValue)
{
return default;
}
return JsonSerializer.Deserialize(value, _jsonOptions);
}
///
/// 获取缓存
///
/// 缓存Key
///
public object Get(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
RedisValue value = _cache.StringGet(GetKeyForRedis(key));
if (!value.HasValue)
{
return null;
}
return JsonSerializer.Deserialize