using Castle.DynamicProxy; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using WIDESEAWCS_Core.Attributes; using WIDESEAWCS_Core.Caches; using WIDESEAWCS_Core.Helper; using ICacheService = WIDESEAWCS_Core.Caches.ICacheService; namespace WIDESEAWCS_Core.AOP { public class CacheAOP : IInterceptor { private readonly ICacheService _cacheService; public CacheAOP(ICacheService cacheService) { _cacheService = cacheService; } public void Intercept(IInvocation invocation) { var method = invocation.MethodInvocationTarget ?? invocation.Method; var cacheAttribute = method.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(CacheAttribute)); if (cacheAttribute is CacheAttribute qCachingAttribute) { //获取自定义缓存键 var cacheKey = CustomCacheKey(invocation); if (_cacheService.Exists(cacheKey)) { //将当前获取到的缓存值,赋值给当前执行方法 Type returnType; if (typeof(Task).IsAssignableFrom(method.ReturnType)) { returnType = method.ReturnType.GenericTypeArguments.FirstOrDefault(); } else { returnType = method.ReturnType; } //根据key获取相应的缓存值 dynamic? cacheValue = _cacheService.Get(returnType, cacheKey); if (cacheValue != null) invocation.ReturnValue = (typeof(Task).IsAssignableFrom(method.ReturnType)) ? Task.FromResult(cacheValue) : cacheValue; return; } //去执行当前的方法 invocation.Proceed(); //存入缓存 if (!string.IsNullOrWhiteSpace(cacheKey)) { object response; //Type type = invocation.ReturnValue?.GetType(); var type = invocation.Method.ReturnType; if (typeof(Task).IsAssignableFrom(type)) { dynamic result = invocation.ReturnValue; response = result.Result; } else { response = invocation.ReturnValue; } if (response == null) response = string.Empty; _cacheService.AddOrUpdate(cacheKey, response.Serialize(), qCachingAttribute.AbsoluteExpiration * 60); } } else { invocation.Proceed(); //直接执行被拦截方法 } } /// /// 自定义缓存的key /// /// /// protected string CustomCacheKey(IInvocation invocation) { var typeName = invocation.TargetType.Name; //获取调用目标类型名称 var methodName = invocation.Method.Name; //获取调用方法名称 var methodArguments = invocation.Arguments.Select(GetArgumentValue).Take(3).ToList();//获取参数列表,最多三个 string key = $"{typeName}:{methodName}:"; //定义key,格式为:类型名称:方法名称: foreach (var param in methodArguments) { key = $"{key}{param}:"; //遍历参数列表,将参数值添加到key中,格式为:参数值: } return key.TrimEnd(':'); //返回key,去掉末尾的冒号 } /// /// object 转 string /// /// /// protected static string GetArgumentValue(object arg) { if (arg is DateTime) // 如果arg是DateTime类型,则返回其字符串表示形式 return ((DateTime)arg).ToString("yyyyMMddHHmmss"); if (!arg.IsNotEmptyOrNull()) // 如果arg不是空或null,则返回其字符串表示形式 return arg.ObjToString(); if (arg != null) { // 如果arg不是空或null if (arg is Expression) { // 如果arg是Expression类型 var obj = arg as Expression; // 解析arg var result = Resolve(obj); // 返回MD5加密后的字符串 return MD5Helper.MD5Encrypt16(result); } else if (arg.GetType().IsClass) { // 如果arg是类类型 // 将arg序列化为JSON字符串 return MD5Helper.MD5Encrypt16(JsonConvert.SerializeObject(arg)); } // 否则,返回"value:"加上arg的字符串表示形式 return $"value:{arg.ObjToString()}"; } // 如果arg是空或null,则返回空字符串 return string.Empty; } private static string Resolve(Expression expression) { // 创建一个ExpressionContext对象 ExpressionContext expContext = new ExpressionContext(); // 解析表达式,并指定解析类型为WhereSingle expContext.Resolve(expression, ResolveExpressType.WhereSingle); // 获取解析结果 var value = expContext.Result.GetString(); // 获取参数列表 var pars = expContext.Parameters; // 遍历参数列表 pars.ForEach(s => { // 将参数名替换为参数值 value = value.Replace(s.ParameterName, s.Value.ObjToString()); }); // 返回替换后的值 return value; } } }