using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using StackExchange.Redis; namespace Permission.Redis { public class RedisService : IRedisService { private readonly IConfiguration _config; private IDatabase _db; public RedisService(IConfiguration config, string databaseName, int db = 0) { _config = config; _db = RedisClientSingleton.GetInstance(_config).GetDatabase(databaseName, db); } #region String 操作 public bool StringSet(string redisKey, string redisValue, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); return _db.StringSet(redisKey, redisValue, expiry); } public bool StringSet(IEnumerable> keyValuePairs) { var pairs = keyValuePairs.Select(x => new KeyValuePair(AddKeyPrefix(x.Key), x.Value)); return _db.StringSet(pairs.ToArray()); } public string StringGet(string redisKey, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); return _db.StringGet(redisKey); } public bool StringSet(string redisKey, T redisValue, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); var json = Serialize(redisValue); return _db.StringSet(redisKey, json, expiry); } public T StringGet(string redisKey, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); return Deserialize(_db.StringGet(redisKey)); } #region String 异步操作 public async Task StringSetAsync(string redisKey, string redisValue, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); return await _db.StringSetAsync(redisKey, redisValue, expiry); } public async Task StringSetAsync(IEnumerable> keyValuePairs) { var pairs = keyValuePairs.Select(x => new KeyValuePair(AddKeyPrefix(x.Key), x.Value)); return await _db.StringSetAsync(pairs.ToArray()); } public async Task StringGetAsync(string redisKey, string redisValue, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); return await _db.StringGetAsync(redisKey); } public async Task StringSetAsync(string redisKey, T redisValue, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); var json = Serialize(redisValue); return await _db.StringSetAsync(redisKey, json, expiry); } public async Task StringGetAsync(string redisKey, TimeSpan? expiry = null) { redisKey = AddKeyPrefix(redisKey); return Deserialize(await _db.StringGetAsync(redisKey)); } #endregion #endregion #region Hash 操作 public bool HashExists(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return _db.HashExists(redisKey, hashField); } public bool HashDelete(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return _db.HashDelete(redisKey, hashField); } public long HashDelete(string redisKey, IEnumerable hashFields) { redisKey = AddKeyPrefix(redisKey); var fields = hashFields.Select(x => (RedisValue)x); return _db.HashDelete(redisKey, fields.ToArray()); } public bool HashSet(string redisKey, string hashField, string value) { redisKey = AddKeyPrefix(redisKey); return _db.HashSet(redisKey, hashField, value); } public void HashSet(string redisKey, IEnumerable> hashFields) { redisKey = AddKeyPrefix(redisKey); var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value)); _db.HashSet(redisKey, entries.ToArray()); } public string HashGet(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return _db.HashGet(redisKey, hashField); } public IEnumerable HashGet(string redisKey, IEnumerable hashFields) { redisKey = AddKeyPrefix(redisKey); var fields = hashFields.Select(x => (RedisValue)x); return ConvertStrings(_db.HashGet(redisKey, fields.ToArray())); } public IEnumerable HashKeys(string redisKey) { redisKey = AddKeyPrefix(redisKey); return ConvertStrings(_db.HashKeys(redisKey)); } public IEnumerable HashValues(string redisKey) { redisKey = AddKeyPrefix(redisKey); return ConvertStrings(_db.HashValues(redisKey)); } public bool HashSet(string redisKey, string hashField, T redisValue) { redisKey = AddKeyPrefix(redisKey); var json = Serialize(redisValue); return _db.HashSet(redisKey, hashField, json); } public T HashGet(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return Deserialize(_db.HashGet(redisKey, hashField)); } #region Hash 异步操作 public async Task HashExistsAsync(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return await _db.HashExistsAsync(redisKey, hashField); } public async Task HashDeleteAsync(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return await _db.HashDeleteAsync(redisKey, hashField); } public async Task HashDeleteAsync(string redisKey, IEnumerable hashFields) { redisKey = AddKeyPrefix(redisKey); var fields = hashFields.Select(x => (RedisValue)x); return await _db.HashDeleteAsync(redisKey, fields.ToArray()); } public async Task HashSetAsync(string redisKey, string hashField, string value) { redisKey = AddKeyPrefix(redisKey); return await _db.HashSetAsync(redisKey, hashField, value); } public async Task HashSetAsync(string redisKey, IEnumerable> hashFields) { redisKey = AddKeyPrefix(redisKey); var entries = hashFields.Select(x => new HashEntry(AddKeyPrefix(x.Key), x.Value)); await _db.HashSetAsync(redisKey, entries.ToArray()); } public async Task HashGetAsync(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return await _db.HashGetAsync(redisKey, hashField); } public async Task> HashGetAsync(string redisKey, IEnumerable hashFields, string value) { redisKey = AddKeyPrefix(redisKey); var fields = hashFields.Select(x => (RedisValue)x); return ConvertStrings(await _db.HashGetAsync(redisKey, fields.ToArray())); } public async Task> HashKeysAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return ConvertStrings(await _db.HashKeysAsync(redisKey)); } public async Task> HashValuesAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return ConvertStrings(await _db.HashValuesAsync(redisKey)); } public async Task HashSetAsync(string redisKey, string hashField, T value) { redisKey = AddKeyPrefix(redisKey); var json = Serialize(value); return await _db.HashSetAsync(redisKey, hashField, json); } public async Task HashGetAsync(string redisKey, string hashField) { redisKey = AddKeyPrefix(redisKey); return Deserialize(await _db.HashGetAsync(redisKey, hashField)); } #endregion #endregion #region List 操作 public string ListLeftPop(string redisKey) { redisKey = AddKeyPrefix(redisKey); return _db.ListLeftPop(redisKey); } public string ListRightPop(string redisKey) { redisKey = AddKeyPrefix(redisKey); return _db.ListRightPop(redisKey); } public long ListRemove(string redisKey, string redisValue) { redisKey = AddKeyPrefix(redisKey); return _db.ListRemove(redisKey, redisValue); } public long ListRightPush(string redisKey, string redisValue) { redisKey = AddKeyPrefix(redisKey); return _db.ListRightPush(redisKey, redisValue); } public long ListLeftPush(string redisKey, string redisValue) { redisKey = AddKeyPrefix(redisKey); return _db.ListLeftPush(redisKey, redisValue); } public long ListLength(string redisKey) { redisKey = AddKeyPrefix(redisKey); return _db.ListLength(redisKey); } public IEnumerable ListRange(string redisKey, long start = 0, long stop = -1) { redisKey = AddKeyPrefix(redisKey); return ConvertStrings(_db.ListRange(redisKey, start, stop)); } public T ListLeftPop(string redisKey) { redisKey = AddKeyPrefix(redisKey); return Deserialize(_db.ListLeftPop(redisKey)); } public T ListRightPop(string redisKey) { redisKey = AddKeyPrefix(redisKey); return Deserialize(_db.ListRightPop(redisKey)); } public long ListRightPush(string redisKey, T redisValue) { redisKey = AddKeyPrefix(redisKey); return _db.ListRightPush(redisKey, Serialize(redisValue)); } public long ListLeftPush(string redisKey, T redisValue) { redisKey = AddKeyPrefix(redisKey); return _db.ListLeftPush(redisKey, Serialize(redisValue)); } #region List 异步操作 public async Task ListLeftPopAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return await _db.ListLeftPopAsync(redisKey); } public async Task ListRightPopAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return await _db.ListRightPopAsync(redisKey); } public async Task ListRemoveAsync(string redisKey, string redisValue) { redisKey = AddKeyPrefix(redisKey); return await _db.ListRemoveAsync(redisKey, redisValue); } public async Task ListRightPushAsync(string redisKey, string redisValue) { redisKey = AddKeyPrefix(redisKey); return await _db.ListRightPushAsync(redisKey, redisValue); } public async Task ListLeftPushAsync(string redisKey, string redisValue) { redisKey = AddKeyPrefix(redisKey); return await _db.ListLeftPushAsync(redisKey, redisValue); } public async Task ListLengthAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return await _db.ListLengthAsync(redisKey); } public async Task> ListRangeAsync(string redisKey, long start = 0, long stop = -1) { redisKey = AddKeyPrefix(redisKey); var query = await _db.ListRangeAsync(redisKey, start, stop); return query.Select(x => x.ToString()); } public async Task ListLeftPopAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return Deserialize(await _db.ListLeftPopAsync(redisKey)); } public async Task ListRightPopAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return Deserialize(await _db.ListRightPopAsync(redisKey)); } public async Task ListRightPushAsync(string redisKey, T redisValue) { redisKey = AddKeyPrefix(redisKey); return await _db.ListRightPushAsync(redisKey, Serialize(redisValue)); } public async Task ListLeftPushAsync(string redisKey, T redisValue) { redisKey = AddKeyPrefix(redisKey); return await _db.ListLeftPushAsync(redisKey, Serialize(redisValue)); } #endregion #endregion #region SortedSet 操作 public bool SortedSetAdd(string redisKey, string member, double score) { redisKey = AddKeyPrefix(redisKey); return _db.SortedSetAdd(redisKey, member, score); } public IEnumerable SortedSetRangeByRank(string redisKey, long start = 0L, long stop = -1L, OrderType order = OrderType.Ascending) { redisKey = AddKeyPrefix(redisKey); return _db.SortedSetRangeByRank(redisKey, start, stop, (Order)order).Select(x => x.ToString()); } public long SortedSetLength(string redisKey) { redisKey = AddKeyPrefix(redisKey); return _db.SortedSetLength(redisKey); } public bool SortedSetLength(string redisKey, string memebr) { redisKey = AddKeyPrefix(redisKey); return _db.SortedSetRemove(redisKey, memebr); } public bool SortedSetAdd(string redisKey, T member, double score) { redisKey = AddKeyPrefix(redisKey); var json = Serialize(member); return _db.SortedSetAdd(redisKey, json, score); } public double SortedSetIncrement(string redisKey, string member, double value = 1) { redisKey = AddKeyPrefix(redisKey); return _db.SortedSetIncrement(redisKey, member, value); } #region SortedSet 异步操作 public async Task SortedSetAddAsync(string redisKey, string member, double score) { redisKey = AddKeyPrefix(redisKey); return await _db.SortedSetAddAsync(redisKey, member, score); } public async Task> SortedSetRangeByRankAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return ConvertStrings(await _db.SortedSetRangeByRankAsync(redisKey)); } public async Task SortedSetLengthAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return await _db.SortedSetLengthAsync(redisKey); } public async Task SortedSetRemoveAsync(string redisKey, string memebr) { redisKey = AddKeyPrefix(redisKey); return await _db.SortedSetRemoveAsync(redisKey, memebr); } public async Task SortedSetAddAsync(string redisKey, T member, double score) { redisKey = AddKeyPrefix(redisKey); var json = Serialize(member); return await _db.SortedSetAddAsync(redisKey, json, score); } public async Task SortedSetIncrementAsync(string redisKey, string member, double value = 1) { redisKey = AddKeyPrefix(redisKey); return await _db.SortedSetIncrementAsync(redisKey, member, value); } #endregion #endregion #region key 操作 public bool KeyDelete(string redisKey) { redisKey = AddKeyPrefix(redisKey); return _db.KeyDelete(redisKey); } public long KeyDelete(IEnumerable redisKeys) { var keys = redisKeys.Select(x => (RedisKey)AddKeyPrefix(x)); return _db.KeyDelete(keys.ToArray()); } public bool KeyExists(string redisKey) { redisKey = AddKeyPrefix(redisKey); return _db.KeyExists(redisKey); } public bool KeyRename(string redisKey, string redisNewKey) { redisKey = AddKeyPrefix(redisKey); return _db.KeyRename(redisKey, redisNewKey); } public bool KeyExpire(string redisKey, TimeSpan? expiry) { redisKey = AddKeyPrefix(redisKey); return _db.KeyExpire(redisKey, expiry); } #region key 异步操作 public async Task KeyDeleteAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return await _db.KeyDeleteAsync(redisKey); } public async Task KeyDeleteAsync(IEnumerable redisKeys) { var keys = redisKeys.Select(x => (RedisKey)AddKeyPrefix(x)); return await _db.KeyDeleteAsync(keys.ToArray()); } public async Task KeyExistsAsync(string redisKey) { redisKey = AddKeyPrefix(redisKey); return await _db.KeyExistsAsync(redisKey); } public async Task KeyRenameAsync(string redisKey, string redisNewKey) { redisKey = AddKeyPrefix(redisKey); return await _db.KeyRenameAsync(redisKey, redisNewKey); } public async Task KeyExpireAsync(string redisKey, TimeSpan? expiry) { redisKey = AddKeyPrefix(redisKey); return await _db.KeyExpireAsync(redisKey, expiry); } #endregion #endregion #region 序列化对象 /// /// 添加 Key 的前缀 /// /// /// private string AddKeyPrefix(string key) { var syskey = _config.GetSection("RedisConfig:RedisKey").Value; return syskey + key; } /// /// 转换为字符串 /// /// /// /// private static IEnumerable ConvertStrings(IEnumerable list) where T : struct { if (list == null) throw new ArgumentNullException(nameof(list)); return list.Select(x => x.ToString()); } /// /// 序列化对象 /// /// /// static byte[] Serialize(object obj) { if (obj == null) return null; var binaryFormatter = new BinaryFormatter(); using (var memoryStream = new MemoryStream()) { binaryFormatter.Serialize(memoryStream, obj); var data = memoryStream.ToArray(); return data; } } /// /// 反序列化对象 /// /// /// /// static T Deserialize(byte[] data) { if (data == null) return default(T); var binaryFormatter = new BinaryFormatter(); using (var memoryStream = new MemoryStream(data)) { var result = (T)binaryFormatter.Deserialize(memoryStream); return result; } } #endregion } }