protected override void InterceptSync(IInvocation invocation) { CacheInterceptorContext context = null; context = GetCacheInterceptorContext(invocation); var key = BuildCacheKey(invocation, context); if (context.CacheAttr.Invalidate) { var prefix = context.CacheAttr.Prefix; if (string.IsNullOrWhiteSpace(prefix)) { prefix = context.ClassName; } CacheClient.RemoveByPrefixAsync(prefix).GetAwaiter().GetResult(); base.InterceptSync(invocation); } else { var cacheResultTask = (dynamic)context.GetFromCacheMethodInfo.Invoke(CacheClient, new string[] { key }); var cacheResult = cacheResultTask.GetAwaiter().GetResult(); if (cacheResult.HasValue) { invocation.ReturnValue = cacheResult.Value; } else { base.InterceptSync(invocation); //ADD to cache AddToCache(context, key, invocation.ReturnValue); } } }
protected virtual string BuildCacheKey(IInvocation invocation, CacheInterceptorContext context) { var sb = new StringBuilder(); if (!string.IsNullOrWhiteSpace(context.CacheAttr.Prefix)) { sb.Append(context.CacheAttr.Prefix); } else { sb.Append(context.ClassName); sb.Append("."); sb.Append(context.MethodName); } if (context.CacheAttr.IsUserContextAware && ActionContext.Data.ContainsKey("UserId")) { var userId = ActionContext.Data["UserId"].ToString(); sb.Append(".u." + userId); } sb.Append(":"); string output = JsonConvert.SerializeObject(invocation.Arguments, jsonSerializerSettings); sb.Append(output); return(sb.ToString()); }
private void AddToCache(CacheInterceptorContext context, string key, object result) { if (context.CacheAttr.ExpirationType == ExpirationType.Default) { CacheClient.AddAsync(key, result).GetAwaiter().GetResult(); } else if (context.CacheAttr.ExpirationType == ExpirationType.ExpiresIn) { TimeSpan span = TimeSpan.Parse(context.CacheAttr.ExpirationPattern); CacheClient.AddAsync(key, result, span).GetAwaiter().GetResult(); } }
private CacheInterceptorContext GetCacheInterceptorContext(IInvocation invocation) { CacheInterceptorContext context; if (!MethodList.TryGetValue(invocation.Method, out context)) { lock (_lock) { context = new CacheInterceptorContext(); context.MethodName = invocation.Method.Name; context.ClassName = invocation.TargetType.FullName; context.CacheAttr = invocation.Method.GetCustomAttribute <CacheAttribute>(); var methodType = invocation.Method.ReturnType; if (methodType.IsGenericType) { context.GetFromCacheMethodInfo = typeof(ICacheClient).GetMethod("GetAsync") .MakeGenericMethod(new Type[] { methodType.GetGenericArguments()[0] }); var task = Task.FromResult <object>(null); Type taskReturnType = (context.GetFromCacheMethodInfo).ReturnType; //e.g. Task<int> var type = taskReturnType.GetGenericArguments()[0].GetGenericArguments()[0]; //get the result type, e.g. int var convert_method = this.GetType().GetMethod("Convert").MakeGenericMethod(type); //Get the closed version of the Convert method, e.g. Convert<int> context.CreateNewInstanceMethodInfo = convert_method; } else { context.GetFromCacheMethodInfo = typeof(ICacheClient).GetMethod("GetAsync") .MakeGenericMethod(new Type[] { methodType }); } if (MethodList.ContainsKey(invocation.Method)) { MethodList[invocation.Method] = context; } else { MethodList.Add(invocation.Method, context); } } } return(context); }