private async Task ProcessGetOrCreateAsync(AspectContext context, AspectDelegate next) { if (GetMethodAttributes(context.ServiceMethod) is EniymCacheGetOrCreateAttribute attribute) { if (string.IsNullOrEmpty(attribute.Template)) { throw new ArgumentNullException($"please set the cache key '{nameof(attribute.Template)}'"); } var returnType = context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType; var cacheKey = KeyGenerator.GetCacheKey(context, attribute.Template); Logger.LogInformation($"KeyGenerator.GetCacheKey: '{cacheKey}'"); object cacheValue = null; try { cacheValue = await CacheProvider.GetAsync(cacheKey, returnType); } catch { Logger.LogError($"An error occurred while reading cache '{cacheKey}'."); cacheValue = null; } if (cacheValue != null) { context.ReturnValue = context.IsAsync() ? TaskResultMethod .GetOrAdd(returnType, t => typeof(Task).GetMethods() .First(p => p.Name == "FromResult" && p.ContainsGenericParameters) .MakeGenericMethod(returnType)).Invoke(null, new object[] { cacheValue }) : cacheValue; } else { await next(context); var returnValue = context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue; if (returnValue != null) { await CacheProvider.SetAsync(cacheKey, returnValue, attribute.CacheSeconds); } } } else { await next(context); } }
public async override Task Invoke(AspectContext context, AspectDelegate next) { Assert.False(context.IsAsync()); await context.Invoke(next); Assert.True(context.IsAsync()); var result = context.UnwrapAsyncReturnValue(); Assert.Equal(100, result); }
/// <summary> /// Proceeds the able async. /// </summary> /// <returns>The able async.</returns> /// <param name="context">Context.</param> /// <param name="next">Next.</param> private async Task ProceedAbleAsync(AspectContext context, AspectDelegate next) { if (context.ServiceMethod.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(EasyCachingAbleAttribute)) is EasyCachingAbleAttribute attribute) { var returnType = context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType; var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix); object cacheValue = await CacheProvider.GetAsync(cacheKey, returnType); if (cacheValue != null) { if (context.IsAsync()) { //#1 //dynamic member = context.ServiceMethod.ReturnType.GetMember("Result")[0]; //dynamic temp = System.Convert.ChangeType(cacheValue.Value, member.PropertyType); //context.ReturnValue = System.Convert.ChangeType(Task.FromResult(temp), context.ServiceMethod.ReturnType); //#2 context.ReturnValue = TypeofTaskResultMethod.GetOrAdd(returnType, t => typeof(Task).GetMethods().First(p => p.Name == "FromResult" && p.ContainsGenericParameters).MakeGenericMethod(returnType)).Invoke(null, new object[] { cacheValue }); } else { //context.ReturnValue = System.Convert.ChangeType(cacheValue.Value, context.ServiceMethod.ReturnType); context.ReturnValue = cacheValue; } } else { // Invoke the method if we don't have a cache hit await next(context); if (context.IsAsync()) { //get the result var returnValue = await context.UnwrapAsyncReturnValue(); await CacheProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } else { await CacheProvider.SetAsync(cacheKey, context.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration)); } } } else { // Invoke the method if we don't have EasyCachingAbleAttribute await next(context); } }
private async Task DoCaching( AspectContext context, AspectDelegate next, CachingAttribute cachingAttribute ) { var cacheProvider = context.ServiceProvider.GetService(typeof(ICachingProvider)) as ICachingProvider; var cachingKey = GenerateCachingKey(context, cachingAttribute); object cacheValue = await cacheProvider.GetAsync <object>(cachingKey); if (cacheValue != null)// 若读取到缓存就直接返回,否则设置缓存 { if (context.IsAsync()) { PropertyInfo propertyInfo = context.ServiceMethod.ReturnType.GetMember("Result")[0] as PropertyInfo; dynamic returnValue = JsonConvert.DeserializeObject(cacheValue.ToString(), propertyInfo.PropertyType); context.ReturnValue = Task.FromResult(returnValue); } else { context.ReturnValue = JsonConvert.DeserializeObject(cacheValue.ToString(), context.ServiceMethod.ReturnType); } } else { await next(context); // 设置缓存 if (!string.IsNullOrWhiteSpace(cachingKey)) { object returnValue = null; if (context.IsAsync()) { returnValue = await context.UnwrapAsyncReturnValue(); } else { returnValue = context.ReturnValue; } await cacheProvider.SetAsync( cachingKey, returnValue, TimeSpan.FromSeconds(cachingAttribute.Expiration) ); } } }
/// <summary> /// Proceeds the able async. /// </summary> /// <returns>The able async.</returns> /// <param name="context">Context.</param> /// <param name="next">Next.</param> private async Task ProceedAbleAsync(AspectContext context, AspectDelegate next) { var attribute = context.ServiceMethod.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(EasyCachingAbleAttribute)) as EasyCachingAbleAttribute; if (attribute != null) { var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix); var cacheValue = await CacheProvider.GetAsync <object>(cacheKey); if (cacheValue.HasValue) { if (context.IsAsync()) { //#1 dynamic member = context.ServiceMethod.ReturnType.GetMember("Result")[0]; dynamic temp = System.Convert.ChangeType(cacheValue.Value, member.PropertyType); context.ReturnValue = System.Convert.ChangeType(Task.FromResult(temp), context.ServiceMethod.ReturnType); //#2 //... } else { context.ReturnValue = System.Convert.ChangeType(cacheValue.Value, context.ServiceMethod.ReturnType); } } else { // Invoke the method if we don't have a cache hit await next(context); if (context.IsAsync()) { //get the result var returnValue = await context.UnwrapAsyncReturnValue(); await CacheProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } else { await CacheProvider.SetAsync(cacheKey, context.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration)); } } } else { // Invoke the method if we don't have EasyCachingAbleAttribute await next(context); } }
public override async Task Invoke(AspectContext context, AspectDelegate next) { var logger = LogManager.GetLogger("ProxyInterceptor"); var parameters = JsonConvert.SerializeObject(context.Parameters); logger.Info($"Call api {context.ServiceMethod.DeclaringType.FullName}->{context.ServiceMethod.Name} Paramters:{parameters}"); await next(context); if (context.IsAsync()) { if (context.ServiceMethod.ReturnType.FullName == "System.Threading.Tasks.Task") { logger.Info($"Result value: void"); } else { var result = await context.UnwrapAsyncReturnValue(); var res = JsonConvert.SerializeObject(result); logger.Info($"Result value: {res}"); } } else { if (context.ReturnValue != null) { var res = JsonConvert.SerializeObject(context.ReturnValue); logger.Info($"Result value: {res}"); } } }
public async override Task Invoke(AspectContext context, AspectDelegate next) { var Parameters = context.Parameters; await context.Invoke(next); var result = context.IsAsync() ? await context.UnwrapAsyncReturnValue(): context.ReturnValue; }
public async override Task Invoke(AspectContext context, AspectDelegate next) { if (_cacheType.GetInterfaces().Contains(typeof(IDistributedCache))) { } //判断是否是异步方法 bool isAsync = context.IsAsync(); //if (context.ImplementationMethod.GetCustomAttribute(typeof(System.Runtime.CompilerServices.AsyncStateMachineAttribute)) != null) //{ // isAsync = true; //} //先判断方法是否有返回值,无就不进行缓存判断 Type methodReturnType = context.GetReturnParameter().Type; if (methodReturnType == typeof(void) || methodReturnType == typeof(Task) || methodReturnType == typeof(ValueTask)) { await next(context); return; } Type returnType = methodReturnType; if (isAsync) { //取得异步返回的类型 returnType = returnType.GenericTypeArguments.FirstOrDefault(); } //获取方法参数名 //string param = CommonHelper.ObjectToJsonString(context.Parameters); ////获取方法名称,也就是缓存key值 //string key = "Methods:" + context.ImplementationMethod.DeclaringType.FullName + "." + context.ImplementationMethod.Name; //var cache = context.ServiceProvider.GetService<ICacheHelper>(); }
/// <summary> /// Processes the put async. /// </summary> /// <returns>The put async.</returns> /// <param name="context">Context.</param> private async Task ProcessPutAsync(AspectContext context) { if (GetMethodAttributes(context.ServiceMethod).FirstOrDefault(x => x.GetType() == typeof(EasyCachingPutAttribute)) is EasyCachingPutAttribute attribute && context.ReturnValue != null) { var _cacheProvider = CacheProviderFactory.GetCachingProvider(attribute.CacheProviderName ?? Options.Value.CacheProviderName); var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix); try { if (context.IsAsync()) { //get the result var returnValue = await context.UnwrapAsyncReturnValue(); await _cacheProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } else { await _cacheProvider.SetAsync(cacheKey, context.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration)); } } catch (Exception ex) { if (!attribute.IsHightAvailability) { throw; } else { Logger?.LogError(new EventId(), ex, $"Cache provider \"{_cacheProvider.Name}\" set error."); } } } }
/// <summary> /// 执行被拦截方法 /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> private async Task <object> RunAndGetReturn(AspectContext context, AspectDelegate next) { await context.Invoke(next); return(context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue); }
public override async Task Invoke(AspectContext context, AspectDelegate next) { var parameters = context.ServiceMethod.GetParameters(); //判断Method是否包含ref / out参数 if (parameters.Any(it => it.IsIn || it.IsOut)) { await next(context); } else { var key = string.IsNullOrEmpty(CacheKey) ? new CacheKey(context.ServiceMethod, parameters, context.Parameters).GetMemoryCacheKey() : CacheKey; //返回值类型 var returnType = context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType; if (_cache.TryGetValue(key, out object value)) { context.ReturnValue = context.IsAsync() ? _taskResultMethod.MakeGenericMethod(returnType).Invoke(null, new object[] { value }) : value; return; } else { await context.Invoke(next); object returnValue = context.ReturnValue; if (context.ServiceMethod.IsReturnTask()) { returnValue = returnValue.GetPropertyValue("Result"); } _cache.Set(key, returnValue, new MemoryCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(Expiration) }); //await next(context); } } }
/// <summary> /// 获取缓存,并处理返回值 /// </summary> /// <param name="key"></param> /// <param name="type"></param> /// <param name="context"></param> /// <returns></returns> private object GetCahceValue(string key, Type type, AspectContext context) { //从缓存取值 var cacheValue = CacheProvider.Get(key, type); if (cacheValue != null) { context.ReturnValue = context.IsAsync() ? TaskResultMethod.MakeGenericMethod(type).Invoke(null, new object[] { cacheValue }) : cacheValue; } return(cacheValue); }
public override async Task Invoke(AspectContext context, AspectDelegate next) { var validator = (MethodInvocationValidator)context.ServiceProvider.GetService(typeof(MethodInvocationValidator)); MethodInfo method; try { method = context.ImplementationMethod; } catch { method = context.ServiceMethod; } var failures = validator.Validate(method, context.Parameters); var result = failures.ToResult(); if (result.Success) { await next(context); return; } if (context.IsAsync()) { if (context.ImplementationMethod.ReturnType == typeof(Task)) { ThrowValidationException(result); //throw new Exception(result.Data.Select(o=>o.Message).ToJoin()); } else { var returnType = context.ImplementationMethod.ReturnType.GenericTypeArguments[0]; if (typeof(IResultBase).IsAssignableFrom(returnType)) { context.ReturnValue = Task.FromResult(new OperationResponse() { Message = result.Message.IsNullOrEmpty() ? result.Data.Select(o => o.Message).ToJoin() : result.Message, Type = Enums.OperationResponseType.Error }); } else { ThrowValidationException(result); } //ThrowValidationException(result); } } }
public async override Task Invoke(AspectContext context, AspectDelegate next) { try { string key = string.Empty; //自定义的缓存key不存在,再获取类名+方法名或类名+方法名+参数名的组合式key if (!string.IsNullOrEmpty(_cacheKey)) { key = _cacheKey; } else { key = GetKey(context.ServiceMethod, context.Parameters); } var returnType = GetReturnType(context); var cache = context.ServiceProvider.GetService <ICacheHelper>(); object result = null; if (cache.Exists(key)) { var strResult = cache.Get(key); result = strResult; } if (result != null) { context.ReturnValue = ResultFactory(result, returnType, context.IsAsync()); } else { result = await RunAndGetReturn(context, next); if (_expireSecond > 0) { cache.Set(key, result, TimeSpan.FromMinutes(_expireSecond)); } else { cache.Set(key, result); } } } catch (Exception e) { Console.WriteLine(e.Message); throw e; } }
/// <summary> /// 执行后 /// </summary> /// <param name="log">日志操作</param> /// <param name="context">Aspect上下文</param> /// <param name="methodName">方法名</param> private async Task ExecuteAfter(ILog log, AspectContext context, string methodName) { if (context.ServiceMethod.ReturnType == typeof(Task) || context.ServiceMethod.ReturnType == typeof(void) || context.ServiceMethod.ReturnType == typeof(ValueTask)) { return; } var returnValue = context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue; var returnType = returnValue.GetType().FullName; log.Caption($"{context.ServiceMethod.Name}方法执行后") .Method(methodName) .Content($"返回类型: {returnType}, 返回值: {returnValue.SafeString()}"); WriteLog(log); }
public async override Task Invoke(AspectContext context, AspectDelegate next) { var cachedConfigurationProvider = context.ServiceProvider.GetService <IOptionsMonitor <FilterCachedConfiguration> >(); var configCache = context.GetCacheConfigurationByMethodName(cachedConfigurationProvider.CurrentValue); var methodReturnType = context.ProxyMethod.ReturnType; if ( configCache == null || methodReturnType == typeof(void) || methodReturnType == typeof(Task) || methodReturnType == typeof(ValueTask) ) { await next(context); return; } if (string.IsNullOrWhiteSpace(CacheName)) { CacheName = context.GetGenerateKeyByMethodNameAndValues(); } ResponseCacheService = context.ServiceProvider.GetService <IResponseCacheService>(); var returnType = context.IsAsync() ? methodReturnType.GenericTypeArguments.FirstOrDefault() : methodReturnType; var cachedValue = await ResponseCacheService.GetCachedResponseAsync(CacheName, returnType); if (cachedValue != null) { context.SetReturnType(methodReturnType, cachedValue); return; } await next(context); await ResponseCacheService .SetCacheResponseAsync( CacheName, await context.GetReturnValueAsync(), TimeSpan.FromSeconds(configCache.TimeToLiveSeconds ?? TimeToLiveSeconds) ); }
public async override Task Invoke(AspectContext context, AspectDelegate next) { if (!IsOpen || Seconds <= 0) { await next(context); return; } try { var cacheService = context.ServiceProvider.GetService <ICacheService>(); Type returnType = context.GetReturnType(); string key = Utils.GetParamterKey(Prefix, Key, ParamterKey, context.Parameters); var result = cacheService.Get(key, returnType); if (result == null) { await next(context); var value = await context.GetReturnValue(); if (value != null) { cacheService.Set(key, TimeSpan.FromSeconds(Seconds), value); } } else { context.ReturnValue = context.ResultFactory(result, returnType, context.IsAsync()); } } catch (Exception ex) { var logger = context.ServiceProvider.GetService <ILogger <CacheMethodAttribute> >(); logger.LogError($"CacheMethod:Key:{Key},ParamterKey:{ParamterKey} {ex.FormatMessage()}"); await next(context); } }
public static void SetReturnType(this AspectContext context, Type methodReturnType, object value) { if (context.IsAsync()) { var returnType = methodReturnType.GenericTypeArguments.FirstOrDefault(); if (methodReturnType == typeof(Task <>).MakeGenericType(returnType)) { context.ReturnValue = typeof(Task).GetMethod(nameof(Task.FromResult)).MakeGenericMethod(returnType).Invoke(null, new[] { value }); } else if (methodReturnType == typeof(ValueTask <>).MakeGenericType(returnType)) { context.ReturnValue = Activator.CreateInstance(typeof(ValueTask <>).MakeGenericType(returnType), value); } } else { context.ReturnValue = value; } }
/// <summary> /// Processes the put async. /// </summary> /// <returns>The put async.</returns> /// <param name="context">Context.</param> private async Task ProcessPutAsync(AspectContext context) { if (context.ServiceMethod.GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(EasyCachingPutAttribute)) is EasyCachingPutAttribute attribute && context.ReturnValue != null) { var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix); if (context.IsAsync()) { //get the result var returnValue = await context.UnwrapAsyncReturnValue(); await CacheProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } else { await CacheProvider.SetAsync(cacheKey, context.ReturnValue, TimeSpan.FromSeconds(attribute.Expiration)); } } }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> public override async Task Invoke(AspectContext context, AspectDelegate next) { if (context.ServiceMethod.AttributeExists <DisableUnitOfWorkAttribute>() || context.ImplementationMethod.AttributeExists <DisableUnitOfWorkAttribute>()) { await next(context); return; } using (var uow = _unitOfWorkManager.Begin(CreateOptions(context))) { await next(context); if (context.IsAsync()) { await uow.CompleteAsync(); } else { uow.Complete(); } } }
public async override Task Invoke(AspectContext context, AspectDelegate next) { if (!IsOpen) { await next(context); return; } try { var cacheService = context.ServiceProvider.GetService <ICacheService>(); Type returnType = context.GetReturnType(); string key = Utils.GetParamterKey(Prefix, Key, ParamterKey, context.Parameters); var result = cacheService.Get(key, returnType); if (result == null) { await Next(context, next, cacheService, key); } else { context.ReturnValue = context.ResultFactory(result, returnType, context.IsAsync()); } } catch (Exception ex) { var logger = context.ServiceProvider.GetService <ILogger <CacheTiggerAttribute> >(); logger.LogError($"CacheInterceptor:Key:{Key},ParamterKey:{ParamterKey} {ex.FormatMessage()}"); await next(context); } }
/// <summary> /// 执行 /// </summary> public override async Task Invoke(AspectContext context, AspectDelegate next) { List <string> appendKeyArray = null; if (string.IsNullOrWhiteSpace(Key)) { Key = $"{context.ServiceMethod.DeclaringType}.{context.ImplementationMethod.Name}:{context.ServiceMethod.ToString()}"; } else { if (!AppendKeyParameters.TryGetValue(context.ImplementationMethod, out appendKeyArray)) { if (Key.IndexOf("{", StringComparison.Ordinal) > -1) { appendKeyArray = new List <string>(); var matchs = Regex.Matches(Key, @"\{\w*\:?\w*\}", RegexOptions.None); foreach (Match match in matchs) { if (match.Success) { appendKeyArray.Add(match.Value.TrimStart('{').TrimEnd('}')); } } } AppendKeyParameters.TryAdd(context.ImplementationMethod, appendKeyArray); } } var currentCacheKey = Key; if (appendKeyArray != null && appendKeyArray.Count > 0) { // 获取方法的参数 var pars = context.ProxyMethod.GetParameters(); // 设置参数名和值,加入字典 var dicValue = new Dictionary <string, object>(); for (var i = 0; i < pars.Length; i++) { dicValue.Add(pars[i].Name, context.Parameters[i]); } foreach (var key in appendKeyArray) { if (key.Contains(":")) { var arr = key.Split(':'); var keyFirst = arr[0]; var keySecond = arr[1]; if (!dicValue.TryGetValue(keyFirst, out var value)) { throw new Warning( $"Cache {context.ServiceMethod.DeclaringType}.{context.ImplementationMethod.Name} 不包含参数 {keyFirst}"); } var ob = Internal.Helper.ToDictionary(value); if (!ob.TryGetValue(keySecond, out object tokenValue)) { throw new Warning( $"Cache {context.ServiceMethod.DeclaringType}.{context.ImplementationMethod.Name} {keyFirst} 不包含参数 {keySecond}"); } currentCacheKey = currentCacheKey.Replace("{" + key + "}", tokenValue.ToString()); } else { if (!dicValue.TryGetValue(key, out var value)) { throw new Warning( $"Cache {context.ServiceMethod.DeclaringType}.{context.ImplementationMethod.Name} 不包含参数 {key}"); } currentCacheKey = currentCacheKey.Replace("{" + key + "}", value.ToString()); } } } // 返回值类型 var returnType = context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType; // 从缓存取值 var cacheValue = await Cache.GetAsync(currentCacheKey, returnType); if (cacheValue != null) { context.ReturnValue = context.IsAsync() ? TaskResultMethod.MakeGenericMethod(returnType).Invoke(null, new object[] { cacheValue }) : cacheValue; return; } using (await _lock.LockAsync()) { cacheValue = await Cache.GetAsync(currentCacheKey, returnType); if (cacheValue != null) { context.ReturnValue = context.IsAsync() ? TaskResultMethod.MakeGenericMethod(returnType).Invoke(null, new object[] { cacheValue }) : cacheValue; } else { await next(context); dynamic returnValue = context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue; Cache.TryAdd(currentCacheKey, returnValue, Expiration); } } }
public async override Task Invoke(AspectContext context, AspectDelegate next) { CacheAbleAttribute attribute = context.GetAttribute <CacheAbleAttribute>(); if (attribute == null) { await context.Invoke(next); return; } try { Database = RedisClient.GetDatabase(); string cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix); string cacheValue = await GetCacheAsync(cacheKey); Type returnType = context.GetReturnType(); if (string.IsNullOrWhiteSpace(cacheValue)) { if (attribute.OnceUpdate) { string lockKey = $"Lock_{cacheKey}"; RedisValue token = Environment.MachineName; if (await Database.LockTakeAsync(lockKey, token, TimeSpan.FromSeconds(10))) { try { var result = await RunAndGetReturn(context, next); await SetCache(cacheKey, result, attribute.Expiration); return; } finally { await Database.LockReleaseAsync(lockKey, token); } } else { for (int i = 0; i < 5; i++) { Thread.Sleep(i * 100 + 500); cacheValue = await GetCacheAsync(cacheKey); if (!string.IsNullOrWhiteSpace(cacheValue)) { break; } } if (string.IsNullOrWhiteSpace(cacheValue)) { var defaultValue = CreateDefaultResult(returnType); context.ReturnValue = ResultFactory(defaultValue, returnType, context.IsAsync()); return; } } } else { var result = await RunAndGetReturn(context, next); await SetCache(cacheKey, result, attribute.Expiration); return; } } var objValue = await DeserializeCache(cacheKey, cacheValue, returnType); //缓存值不可用 if (objValue == null) { await context.Invoke(next); return; } context.ReturnValue = ResultFactory(objValue, returnType, context.IsAsync()); } catch (Exception) { if (context.ReturnValue == null) { await context.Invoke(next); } } }
/// <summary> /// 获取被拦截方法返回值类型 /// </summary> /// <param name="context"></param> /// <returns></returns> private Type GetReturnType(AspectContext context) { return(context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType); }
private object buildResult(AspectContext context) { return(context.IsAsync() ? context.UnwrapAsyncReturnValue().Result : context.ReturnValue); }
public static Type GetReturnType(this AspectContext context) { return(context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType); }
public async static Task <object> GetReturnValueAsync(this AspectContext context) => context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue;
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> private async Task ProcessRedisCaching(AspectContext context, AspectDelegate next) { var attribute = GetMethodAttributes(context.ServiceMethod).FirstOrDefault(x => x.GetType() == typeof(RedisCachingAttribute)) as RedisCachingAttribute; if (attribute == null) { await context.Invoke(next); } var returnType = context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType; var cacheKey = ""; cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix); if (context.Parameters != null && context.Parameters.Length > 0) { var md5key = Encrypt.Md5By32(Json.ToJson(context.Parameters)); cacheKey = cacheKey + ":" + md5key; } else { var md5key = Encrypt.Md5By32(Json.ToJson(context.ServiceMethod.Name)); cacheKey = cacheKey + ":" + md5key; } object cacheValue = null; var isAvailable = true; try { if (attribute.IsHybridProvider) { cacheValue = await HybridCachingProvider.GetAsync(cacheKey, returnType); } else { var _cacheProvider = CacheProviderFactory.GetCachingProvider(attribute.CacheProviderName ?? Options.Value.CacheProviderName); //cacheValue = await _cacheProvider.GetAsync(cacheKey, returnType); var val = await _cacheProvider.GetAsync <string>(cacheKey); if (val.HasValue) { cacheValue = JsonConvert.DeserializeObject(val.Value, returnType); } } } catch (Exception ex) { if (!attribute.IsHighAvailability) { throw ex; } else { isAvailable = false; } } if (cacheValue != null) { if (context.IsAsync()) { //#1 //dynamic member = context.ServiceMethod.ReturnType.GetMember("Result")[0]; //dynamic temp = System.Convert.ChangeType(cacheValue.Value, member.PropertyType); //context.ReturnValue = System.Convert.ChangeType(Task.FromResult(temp), context.ServiceMethod.ReturnType); //#2 context.ReturnValue = TypeofTaskResultMethod.GetOrAdd(returnType, t => typeof(Task).GetMethods().First(p => p.Name == "FromResult" && p.ContainsGenericParameters).MakeGenericMethod(returnType)).Invoke(null, new object[] { cacheValue }); } else { //context.ReturnValue = System.Convert.ChangeType(cacheValue.Value, context.ServiceMethod.ReturnType); context.ReturnValue = cacheValue; } return; } // Invoke the method if we don't have a cache hit await next(context); try { if (isAvailable) { // get the result var returnValue = context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue; // should we do something when method return null? // 1. cached a null value for a short time // 2. do nothing if (returnValue != null && cacheKey.IsNotWhiteSpaceEmpty()) { if (attribute.IsHybridProvider) { await HybridCachingProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } else { var _cacheProvider = CacheProviderFactory.GetCachingProvider(attribute.CacheProviderName ?? Options.Value.CacheProviderName); //var f = Newtonsoft.Json.JsonConvert.SerializeObject(returnValue); await _cacheProvider.SetAsync(cacheKey, JsonConvert.SerializeObject(returnValue, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, DateTimeZoneHandling = DateTimeZoneHandling.Local }), TimeSpan.FromSeconds(attribute.Expiration)); } } } } catch (Exception ex) { ex.Submit(); } }
/// <summary> /// Proceeds the able async. /// </summary> /// <returns>The able async.</returns> /// <param name="context">Context.</param> /// <param name="next">Next.</param> private async Task ProceedAbleAsync(AspectContext context, AspectDelegate next) { if (GetMethodAttributes(context.ServiceMethod).FirstOrDefault(x => typeof(EasyCachingAbleAttribute).IsAssignableFrom(x.GetType())) is EasyCachingAbleAttribute attribute) { var returnType = context.IsAsync() ? context.ServiceMethod.ReturnType.GetGenericArguments().First() : context.ServiceMethod.ReturnType; var cacheKey = KeyGenerator.GetCacheKey(context.ServiceMethod, context.Parameters, attribute.CacheKeyPrefix); object cacheValue = null; var isAvailable = true; try { if (attribute.IsHybridProvider) { cacheValue = await HybridCachingProvider.GetAsync(cacheKey, returnType); } else { var _cacheProvider = CacheProviderFactory.GetCachingProvider(attribute.CacheProviderName ?? Options.Value.CacheProviderName); cacheValue = await _cacheProvider.GetAsync(cacheKey, returnType); } } catch (Exception ex) { if (!attribute.IsHighAvailability) { throw; } else { isAvailable = false; Logger?.LogError(new EventId(), ex, $"Cache provider get error."); } } if (cacheValue != null) { if (context.IsAsync()) { //#1 //dynamic member = context.ServiceMethod.ReturnType.GetMember("Result")[0]; //dynamic temp = System.Convert.ChangeType(cacheValue.Value, member.PropertyType); //context.ReturnValue = System.Convert.ChangeType(Task.FromResult(temp), context.ServiceMethod.ReturnType); //#2 context.ReturnValue = TypeofTaskResultMethod.GetOrAdd(returnType, t => typeof(Task).GetMethods().First(p => p.Name == "FromResult" && p.ContainsGenericParameters).MakeGenericMethod(returnType)).Invoke(null, new object[] { cacheValue }); } else { //context.ReturnValue = System.Convert.ChangeType(cacheValue.Value, context.ServiceMethod.ReturnType); context.ReturnValue = cacheValue; } } else { // Invoke the method if we don't have a cache hit await next(context); if (isAvailable) { // get the result var returnValue = context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue; // should we do something when method return null? // 1. cached a null value for a short time // 2. do nothing if (returnValue != null) { if (attribute.IsHybridProvider) { await HybridCachingProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } else { var _cacheProvider = CacheProviderFactory.GetCachingProvider(attribute.CacheProviderName ?? Options.Value.CacheProviderName); await _cacheProvider.SetAsync(cacheKey, returnValue, TimeSpan.FromSeconds(attribute.Expiration)); } } } } } else { // Invoke the method if we don't have EasyCachingAbleAttribute await next(context); } }
public static async Task <object> GetReturnValue(this AspectContext context) { return(context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue); }