在.net core 中,使用Microsoft.Extensions.Caching.Redis可以很方便的集成Redis,这里涉及到字节数组转成对象和对象转成字节数组,而我们对此有两个基本要求:
1、要做到不需要在序列化的类上增加序列化标识;
2、要求对返回的对象可以不设定具体类型返回,只返回object,因我们在aop中需要用到这个object.
若使用的是AspectCore做AOP的话,那么拦截处理需要加缓存的事件,如下:
public class CacheAttribute : AbstractInterceptorAttribute { [FromContainer] public ICacheService CacheService { get; set; } public async override Task Invoke(AspectContext context, AspectDelegate next) { var key = new Cachekey(context.ServiceMethod, context.Parameters).GetHashCode().ToString(); var cacheValue = CacheService.Get(key); if (cacheValue != null) { context.ReturnValue = cacheValue; } else { await next(context); if (!string.IsNullOrWhiteSpace(key) && context.ReturnValue != null) CacheService.Add(key, context.ReturnValue); } } }
key是根据方法和传参生成一个HashCode,你也可以用自己的方法去生成这个key,缓存获取的方法如下:
public object Get(string key) { var rValue = _cache.Get(key); if (rValue != null) { var value = Json.ToObject(rValue); return value; } return null; }
Json类代码如下:
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace MyCore.Infrastructure.Helpers { public class Json { /// <summary> /// Json序列化器 /// </summary> static readonly JsonSerializer JsonSerializer = new JsonSerializer(); #region ToObject<T>(将Json字符串转换为对象) /// <summary> /// 将Json字符串转换为对象 /// </summary> /// <param name="json">Json字符串</param> public static T ToObject<T>(string json) { if (string.IsNullOrWhiteSpace(json)) return default(T); return JsonConvert.DeserializeObject<T>(json); } #endregion #region ObjectToByte(将对象转换成字节数组) public static byte[] ObjectToByte(object obj) { var typeName = Reflection.GetTypeName(obj.GetType()); using (var ms = new MemoryStream()) { using (var tw = new StreamWriter(ms)) { using (var jw = new JsonTextWriter(tw)) { jw.WriteStartArray();// [ jw.WriteValue(typeName);// "type" JsonSerializer.Serialize(jw, obj);// obj jw.WriteEndArray();// ] jw.Flush(); return ms.ToArray(); } } } } #endregion #region ToObject(字节数组转成对象) /// <summary> /// 反序列化对象 /// </summary> /// <param name="value">值</param> /// <returns></returns> public static object ToObject(byte[] value) { using (var ms = new MemoryStream(value, writable: false)) { using (var tr = new StreamReader(ms)) { using (var jr = new JsonTextReader(tr)) { jr.Read(); if (jr.TokenType == JsonToken.StartArray) { // 读取类型 var typeName = jr.ReadAsString(); var type = Type.GetType(typeName, throwOnError: true);// 获取类型 // 读取对象 jr.Read(); return JsonSerializer.Deserialize(jr, type); } else { throw new InvalidDataException("JsonTranscoder 仅支持 [\"TypeName\", object]"); } } } } } #endregion #region ToJson(将对象转换为Json字符串) /// <summary> /// 将对象转换为Json字符串 /// </summary> /// <param name="target">目标对象</param> /// <param name="isConvertToSingleQuotes">是否将双引号转成单引号</param> public static string ToJson(object target, bool isConvertToSingleQuotes = false) { if (target == null) return "{}"; var result = JsonConvert.SerializeObject(target); if (isConvertToSingleQuotes) result = result.Replace("\"", "'"); return result; } #endregion } }