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; }
/// <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 async override Task Invoke(AspectContext context, AspectDelegate next) { Assert.True(context.IsAsync()); await context.Invoke(next); var result = context.UnwrapAsyncReturnValue(); Assert.Equal(100, result); }
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); } }
/// <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); var res = JsonConvert.SerializeObject(await context.UnwrapAsyncReturnValue()); logger.Info($"Result value: {res}"); }
public override async Task Invoke(AspectContext context, AspectDelegate next) { if (context.Proxy is Service service) { service.CurrentValue = null; await context.Invoke(next); var value = await context.UnwrapAsyncReturnValue(); service.CurrentValue = value; } else { await context.Invoke(next); } }
/// <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); }
/// <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)); } } }
private object buildResult(AspectContext context) { return(context.IsAsync() ? context.UnwrapAsyncReturnValue().Result : context.ReturnValue); }
public static async Task <object> GetReturnValue(this AspectContext context) { return(context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue); }
public async override Task Invoke(AspectContext context, AspectDelegate next) { var returnType = context.GetReturnParameter().Type; var hasCache = context.ImplementationMethod.GetCustomAttributes(typeof(CacheAttribute), false).Any(); if (returnType == typeof(void) || returnType == typeof(Task) || returnType == typeof(ValueTask) || !hasCache) { await next(context); return; } if (context.IsAsync()) { returnType = returnType.GenericTypeArguments.FirstOrDefault(); } var cacheKey = this.CreateCacheKey(context); this.Log("trying to get", cacheKey); var cacheService = (ICacheService)context.ServiceProvider.GetService(typeof(ICacheService)); var cachedResult = cacheService.Get(cacheKey); if (cachedResult == null) { this.Log("key not found", cacheKey); await next(context); var returnValue = context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue; this.Log("trying to set", cacheKey); if (!cacheService.Set(cacheKey, returnValue)) { this.Log("failed to set", cacheKey); } } else { this.Log("found key", cacheKey); if (context.IsAsync()) { if (context.ImplementationMethod.ReturnType == typeof(Task <>).MakeGenericType(returnType)) { context.ReturnValue = typeof(Task) .GetMethod(nameof(Task.FromResult)) .MakeGenericMethod(returnType) .Invoke(null, new[] { cachedResult }); } if (context.ImplementationMethod.ReturnType == typeof(ValueTask <>).MakeGenericType(returnType)) { context.ReturnValue = Activator .CreateInstance(typeof(ValueTask <>).MakeGenericType(returnType), cachedResult); } } else { context.ReturnValue = cachedResult; } } }
/// <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(); } }
public async static Task <object> GetReturnValueAsync(this AspectContext context) => context.IsAsync() ? await context.UnwrapAsyncReturnValue() : context.ReturnValue;
/// <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); } } }
/// <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); } }