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}:"; foreach (var param in methodArguments) { key = $"{key}{param}:"; } return key.TrimEnd(':'); } /// /// object 转 string /// /// /// protected static string GetArgumentValue(object arg) { if (arg is DateTime) return ((DateTime)arg).ToString("yyyyMMddHHmmss"); if (!arg.IsNotEmptyOrNull()) return arg.ObjToString(); if (arg != null) { if (arg is Expression) { var obj = arg as Expression; var result = Resolve(obj); return MD5Helper.MD5Encrypt16(result); } else if (arg.GetType().IsClass) { return MD5Helper.MD5Encrypt16(JsonConvert.SerializeObject(arg)); } return $"value:{arg.ObjToString()}"; } return string.Empty; } private static string Resolve(Expression expression) { ExpressionContext expContext = new ExpressionContext(); 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; } } }