在.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
}
}