public async Task Advise(MethodAsyncAdviceContext context) { SnapshotProfile profile = Profile.Value; if (profile == null) { await context.ProceedAsync(); return; } if (!context.HasReturnValue) { return; } string folderPath = Path.Combine( profile.FolderPath, context.TargetType.FullName, context.TargetMethod.Name); string filePath = GetFilePath(context.TargetMethod, context.Arguments, folderPath); if (profile.Mode == SnapshotMode.Read) { context.ReturnValue = ReadReturnTaskResult(context.TargetMethod, filePath); } else if (profile.Mode == SnapshotMode.Write) { await context.ProceedAsync(); WriteReturnTaskResult(context.ReturnValue, context.TargetMethod, folderPath, filePath); } }
public async Task Advise(MethodAsyncAdviceContext context) { var service = (ServiceBase)context.Target; if (service.BalanceManagementDbContext.Database.CurrentTransaction == null) { await using var transaction = await service.BalanceManagementDbContext.Database.BeginTransactionAsync(); try { await context.ProceedAsync(); await transaction.CommitAsync(); } catch { await transaction.RollbackAsync(); throw; } } else { await context.ProceedAsync(); } }
public Task Advise(MethodAsyncAdviceContext context) { List <ValidationError> errors = new List <ValidationError>(); if (ArgumentNames) { ParameterInfo[] parameters = context.TargetMethod.GetParameters(); int i = 0; foreach (object argument in context.Arguments) { errors.AddRange(argument.ValidateAnnotations(parameters[i++].Name)); } } else { foreach (object argument in context.Arguments) { errors.AddRange(argument.ValidateAnnotations()); } } if (errors.Count > 0) { throw new ValidationException(errors.ToArray()); } return(context.ProceedAsync()); }
internal static bool IsAsync(this MethodAsyncAdviceContext ctx) { var methodInfo = ctx.TargetMethod as MethodInfo; var attrib = methodInfo.GetAttribute <AsyncStateMachineAttribute>(); return(attrib != null); }
public async Task Advise(MethodAsyncAdviceContext context) { using (var t = TracerFactory.StartTracer(context.TargetType, context.TargetMethod.Name)) { if (info.ContainsCharacters()) t.SetAdidtionalInformation(info); try { if (!context.IsTargetMethodAsync) Task.Run(() => context.ProceedAsync()).Wait(); else await context.ProceedAsync(); } catch (AggregateException aex) { if (aex.InnerExceptions == null) { SetErrorInfo(t, aex.Flatten()); throw aex.Flatten(); }; if (aex.InnerExceptions.Count > 1) { SetErrorInfo(t, aex.Flatten()); throw aex.Flatten(); } var ex = aex.InnerException; SetErrorInfo(t, ex); throw ex; } catch (Exception ex) { SetErrorInfo(t, ex); throw; } } }
public async Task Advise(MethodAsyncAdviceContext context) { var parameters = context.TargetMethod.GetParameters(); var parameterDescription = string.Join(", ", parameters.Select(p => $"{p.ParameterType.Name} {p.Name}")); var signature = $"{context.Target ?? context.TargetType}.{context.TargetName}({parameterDescription})"; using (var operation = TelemetryClient.StartOperation <DependencyTelemetry>(signature)) { try { await context.ProceedAsync(); } catch (Exception) { operation.Telemetry.Success = false; throw; } finally { operation.Telemetry.Type = Type; EnrichRequestTelemetry(operation.Telemetry, context, parameters); } } }
public async Task Advise(MethodAsyncAdviceContext context) { var target = (AsyncTest)context.Target; await context.ProceedAsync(); Assert.AreEqual(AsyncTest.FinalStep, target.AwaitStep); }
private static void EnrichRequestTelemetry(ISupportProperties telemetry, MethodAsyncAdviceContext context, IReadOnlyList<ParameterInfo> parameters) { telemetry.Properties.Add( new KeyValuePair<string, string>("Accessibility", context.TargetMethod.Attributes.ToVisibilityScope().ToString())); for (var i = 0; i < context.Arguments.Count; i++) { telemetry.Properties.Add($"ARG {parameters[i].Name}", context.Arguments[i].ToString()); } }
public async Task Advise(MethodAsyncAdviceContext context) { try { await context.ProceedAsync(); } catch (CustomException) { throw new CustomException2(); } }
public async Task Advise(MethodAsyncAdviceContext context) { var method = (MethodInfo)context.TargetMethod; var call = ApiHelper.GetCall(method); var response = await _client.SendAsync(new HttpRequestMessage(call.HttpMethod, call.Address)); if (method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>)) { context.ReturnValue = Task.FromResult(JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync(), method.ReturnType.GetGenericArguments()[0])); } }
public Args(MethodAsyncAdviceContext context) { AsyncContext = context; Arguments = context.Arguments; HasReturnValue = context.HasReturnValue; Method = context.TargetMethod; MethodName = context.TargetName; IsTargetMethodAsync = context.IsTargetMethodAsync; if (context.HasReturnValue) { ReturnValue = context.ReturnValue; } }
public async Task Advise(MethodAsyncAdviceContext context) { MethodInterceptionArgs args = new MethodInterceptionArgs(context); if (args.IsTargetMethodAsync) { await OnInvokeAsync(args); } else { OnInvoke(args); } }
public async Task Advise(MethodAsyncAdviceContext context) { MethodInfo methodInfo = (MethodInfo)context.TargetMethod; Type returnType = methodInfo.ReturnType.GetGenericArguments()[0]; IApiResponse response; try { await context.ProceedAsync(); return; } catch (ValidationException exception) { response = (IApiResponse)Activator.CreateInstance(returnType); response.ValidationErrors = exception.Errors; } catch (BusinessException exception) { response = (IApiResponse)Activator.CreateInstance(returnType); response.ErrorMessage = exception.Message; IApiError error = response as IApiError; if (error != null) { error.ErrorCode = exception.Code; } } catch (Exception exception) { response = (IApiResponse)Activator.CreateInstance(returnType); response.ErrorMessage = exception.Message; IBusinessException businessException = exception as IBusinessException; if (businessException != null) { IApiError error = response as IApiError; if (error != null) { error.ErrorCode = businessException.Code; } } } response.IsSuccess = false; context.ReturnValue = Task.FromResult(response); }
public async Task Advise(MethodAsyncAdviceContext context) { await context.ProceedAsync(); if (context.HasReturnValue) { if (context.ReturnValue is Task) { context.ReturnValue = Plus(((dynamic)context.ReturnValue).Result, 1); } else { context.ReturnValue = (int)context.ReturnValue + 1; } } }
public async Task Advise(MethodAsyncAdviceContext context) { //Logger initilizer here Console.WriteLine($"{context.TargetType.Name} started..."); try { await context.ProceedAsync(); // this calls the original method } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Console.WriteLine($"{context.TargetType.Name} completed..."); } }
/// <summary> /// 拦截方法 /// </summary> /// <param name="context">方法元数据</param> public async Task Advise(MethodAsyncAdviceContext context) { if (context.Target is ScreenBase screenBase) { screenBase.Busy(); await context.ProceedAsync(); screenBase.Idle(); } if (context.Target is OneActiveConductorBase oneActiveConductorBase) { oneActiveConductorBase.Busy(); await context.ProceedAsync(); oneActiveConductorBase.Idle(); } }
public async Task Advise(MethodAsyncAdviceContext context) { using (var t = TracerFactory.StartTracer(context.TargetType, context.TargetMethod.Name)) { if (info.ContainsCharacters()) { t.SetAdidtionalInformation(info); } try { if (!context.IsTargetMethodAsync) { Task.Run(() => context.ProceedAsync()).Wait(); } else { await context.ProceedAsync(); } } catch (AggregateException aex) { if (aex.InnerExceptions == null) { SetErrorInfo(t, aex.Flatten()); throw aex.Flatten(); } ; if (aex.InnerExceptions.Count > 1) { SetErrorInfo(t, aex.Flatten()); throw aex.Flatten(); } var ex = aex.InnerException; SetErrorInfo(t, ex); throw ex; } catch (Exception ex) { SetErrorInfo(t, ex); throw; } } }
public async Task Advise(MethodAsyncAdviceContext context) { try { await context.ProceedAsync(); } catch (Exception ex) { MethodExecutionArgs args = new MethodExecutionArgs(context, ex); OnException(args); if (args.FlowBehavior == FlowBehavior.RethrowException) { throw; } if (args.FlowBehavior == FlowBehavior.ThrowException) { throw ex; } } }
public async Task Advise(MethodAsyncAdviceContext context) { MethodExecutionArgs args = new MethodExecutionArgs(context, null); try { OnEntry(args); await context.ProceedAsync(); OnSuccess(args); } catch (Exception ex) { args.SetException(ex); OnException(args); } finally { OnExit(args); } }
private static AdviceContext CreateAdviceContext(AdviceValues adviceValues, AspectInfo aspectInfo) { AdviceContext adviceContext = new InnerMethodContext(adviceValues, aspectInfo.PointcutMethod, aspectInfo.PointcutMethodDelegate); for (var adviceIndex = aspectInfo.Advices.Count - 1; adviceIndex >= 0; adviceIndex--) { var advice = aspectInfo.Advices[adviceIndex]; // aspects are processed from highest to lowest level, so they are linked here in the opposite order // 3. as parameter if (advice.ParameterAdvice != null && advice.ParameterIndex.HasValue) { var parameterIndex = advice.ParameterIndex.Value; var parameterInfo = GetParameterInfo(aspectInfo.AdvisedMethod, parameterIndex); adviceContext = new ParameterAdviceContext(advice.ParameterAdvice, parameterInfo, parameterIndex, adviceValues, adviceContext); } // 2. as method if (advice.MethodAdvice != null) { adviceContext = new MethodAdviceContext(advice.MethodAdvice, aspectInfo.AdvisedMethod, adviceValues, adviceContext); } // 2b. as async method if (advice.AsyncMethodAdvice != null) { adviceContext = new MethodAsyncAdviceContext(advice.AsyncMethodAdvice, aspectInfo.AdvisedMethod, adviceValues, adviceContext); } // 1. as property if (advice.PropertyAdvice != null && aspectInfo.PointcutProperty != null) { adviceContext = new PropertyAdviceContext(advice.PropertyAdvice, aspectInfo.PointcutProperty, aspectInfo.IsPointcutPropertySetter, adviceValues, adviceContext); } // 1b. as event if (advice.EventAdvice != null && aspectInfo.PointcutEvent != null) { adviceContext = new EventAdviceContext(advice.EventAdvice, aspectInfo.PointcutEvent, aspectInfo.IsPointcutEventAdder, adviceValues, adviceContext); } } return(adviceContext); }
public MethodInterceptionArgs(MethodAsyncAdviceContext context) : base(context) { }
internal static bool IsAwaitable(this MethodAsyncAdviceContext ctx) { var methodInfo = ctx.TargetMethod as MethodInfo; return(methodInfo != null && typeof(Task).IsAssignableFrom(methodInfo.ReturnType)); }
public Task Advise(MethodAsyncAdviceContext context) { return(context.ProceedAsync()); }
/// <summary> /// Runs a method interception. /// We use a static method here, if one day we want to reuse Invocations or change mecanism, /// it will be easier from C# code /// </summary> /// <param name="target">The target.</param> /// <param name="parameters">The parameters.</param> /// <param name="methodHandle">The method handle.</param> /// <param name="innerMethodHandle">The inner method handle.</param> /// <param name="delegatableMethodHandle">The delegatable method handle.</param> /// <param name="typeHandle">The type handle.</param> /// <param name="abstractedTarget">if set to <c>true</c> [abstracted target].</param> /// <param name="genericArguments">The generic arguments (to static type and/or method) in a single array.</param> /// <returns></returns> // ReSharper disable once UnusedMember.Global // ReSharper disable once UnusedMethodReturnValue.Global public static object ProceedAdvice2(object target, object[] parameters, RuntimeMethodHandle methodHandle, RuntimeMethodHandle innerMethodHandle, RuntimeMethodHandle delegatableMethodHandle, RuntimeTypeHandle typeHandle, bool abstractedTarget, Type[] genericArguments) { var aspectInfo = GetAspectInfo(methodHandle, innerMethodHandle, delegatableMethodHandle, typeHandle, abstractedTarget, genericArguments); // this is the case with auto implemented interface if (target is AdvisedInterface advisedInterface) { aspectInfo = aspectInfo.AddAdvice(new AdviceInfo(advisedInterface.Advice)); } foreach (var advice in aspectInfo.Advices) { InjectIntroducedFields(advice, aspectInfo.AdvisedMethod.DeclaringType); } // from here, we build an advice chain, with at least one final advice: the one who calls the method var adviceValues = new AdviceValues(target, aspectInfo.AdvisedMethod.DeclaringType, parameters); // at least there is one context AdviceContext adviceContext = new InnerMethodContext(adviceValues, aspectInfo.PointcutMethod, aspectInfo.PointcutMethodDelegate); for (var adviceIndex = aspectInfo.Advices.Count - 1; adviceIndex >= 0; adviceIndex--) { var advice = aspectInfo.Advices[adviceIndex]; // aspects are processed from highest to lowest level, so they are linked here in the opposite order // 3. as parameter if (advice.ParameterAdvice != null && advice.ParameterIndex.HasValue) { var parameterIndex = advice.ParameterIndex.Value; var parameterInfo = GetParameterInfo(aspectInfo.AdvisedMethod, parameterIndex); adviceContext = new ParameterAdviceContext(advice.ParameterAdvice, parameterInfo, parameterIndex, adviceValues, adviceContext); } // 2. as method if (advice.MethodAdvice != null) { adviceContext = new MethodAdviceContext(advice.MethodAdvice, aspectInfo.AdvisedMethod, adviceValues, adviceContext); } // 2b. as async method if (advice.AsyncMethodAdvice != null) { adviceContext = new MethodAsyncAdviceContext(advice.AsyncMethodAdvice, aspectInfo.AdvisedMethod, adviceValues, adviceContext); } // 1. as property if (advice.PropertyAdvice != null && aspectInfo.PointcutProperty != null) { adviceContext = new PropertyAdviceContext(advice.PropertyAdvice, aspectInfo.PointcutProperty, aspectInfo.IsPointcutPropertySetter, adviceValues, adviceContext); } // 1b. as event if (advice.EventAdvice != null && aspectInfo.PointcutEvent != null) { adviceContext = new EventAdviceContext(advice.EventAdvice, aspectInfo.PointcutEvent, aspectInfo.IsPointcutEventAdder, adviceValues, adviceContext); } } // if the method is no task, then we return immediately // (and the adviceTask is completed) var adviceTask = adviceContext.Invoke(); var advisedMethodInfo = aspectInfo.AdvisedMethod as MethodInfo; var returnType = advisedMethodInfo?.ReturnType; // no Task means aspect was sync, so everything already ended // or it may also been an async void, meaning that we don't care about it if (adviceTask == null || returnType == null || !typeof(Task).GetAssignmentReader().IsAssignableFrom(returnType)) { adviceTask?.Wait(); return(adviceValues.ReturnValue); } // otherwise, see if it is a Task or Task<> // Task is simple too: the advised method is a subtask, // so the advice is completed after the method is completed too if (returnType == typeof(Task)) { return(adviceTask); } // only Task<> left here var taskType = returnType.GetTaskType(); // a reflection equivalent of ContinueWith<TNewResult>, but this TNewResult, under taskType is known only at run-time return(adviceTask.ContinueWith(t => GetResult(t, adviceValues), taskType)); }
public async Task Advise(MethodAsyncAdviceContext context) { await context.ProceedAsync(); }
public MethodExecutionArgs(MethodAsyncAdviceContext context, Exception exception) : base(context) { Exception = exception; }
public async Task Advise(MethodAsyncAdviceContext context) { await context.ProceedAsync(); Console.WriteLine("Success!"); }
public async Task Advise(MethodAsyncAdviceContext context) { await context.ProceedAsync(); context.ReturnValue = Plus(((dynamic)context.ReturnValue).Result, 1); }
/// <summary> /// Runs a method interception. /// We use a static method here, if one day we want to reuse Invocations or change mecanism, /// it will be easier from C# code /// </summary> /// <param name="target">The target.</param> /// <param name="parameters">The parameters.</param> /// <param name="methodBase">The raw method base.</param> /// <param name="innerMethod">The inner method.</param> /// <param name="abstractedTarget">if set to <c>true</c> [abstracted target].</param> /// <param name="genericArguments">The generic arguments (to static type and/or method) in a single array.</param> /// <returns></returns> // ReSharper disable once UnusedMember.Global // ReSharper disable once UnusedMethodReturnValue.Global public static object ProceedAdvice(object target, object[] parameters, MethodBase methodBase, MethodBase innerMethod, bool abstractedTarget, Type[] genericArguments) { var aspectInfo = GetAspectInfo(methodBase, innerMethod, abstractedTarget, genericArguments); // this is the case with auto implemented interface var advisedInterface = target as AdvisedInterface; if (advisedInterface != null) { aspectInfo = aspectInfo.AddAdvice(new AdviceInfo(advisedInterface.Advice)); } foreach (var advice in aspectInfo.Advices.Select(a => a.Advice).Distinct()) { InjectIntroducedFields(advice, methodBase.DeclaringType); } // from here, we build an advice chain, with at least one final advice: the one who calls the method var adviceValues = new AdviceValues(target, aspectInfo.AdvisedMethod.DeclaringType, parameters); // at least there is one context AdviceContext adviceContext = new InnerMethodContext(adviceValues, aspectInfo.PointcutMethod); foreach (var advice in aspectInfo.Advices.Reverse()) { // aspects are processed from highest to lowest level, so they are linked here in the opposite order // 3. as parameter if (advice.ParameterAdvice != null && advice.ParameterIndex.HasValue) { var parameterIndex = advice.ParameterIndex.Value; var parameterInfo = GetParameterInfo(aspectInfo.AdvisedMethod, parameterIndex); adviceContext = new ParameterAdviceContext(advice.ParameterAdvice, parameterInfo, parameterIndex, adviceValues, adviceContext); } // 2. as method if (advice.MethodAdvice != null) { adviceContext = new MethodAdviceContext(advice.MethodAdvice, aspectInfo.AdvisedMethod, adviceValues, adviceContext); } // 2b. as async method if (advice.AsyncMethodAdvice != null) { adviceContext = new MethodAsyncAdviceContext(advice.AsyncMethodAdvice, aspectInfo.AdvisedMethod, adviceValues, adviceContext); } // 1. as property if (advice.PropertyAdvice != null && aspectInfo.PointcutProperty != null) { adviceContext = new PropertyAdviceContext(advice.PropertyAdvice, aspectInfo.PointcutProperty, aspectInfo.IsPointcutPropertySetter, adviceValues, adviceContext); } } // if the method is no task, then we return immediately // (and the adviceTask is completed) var adviceTask = adviceContext.Invoke(); var advisedMethodInfo = aspectInfo.AdvisedMethod as MethodInfo; var returnType = advisedMethodInfo?.ReturnType; // no Task means aspect was sync, so everything already ended // TODO: this is actually not true, since an async method can be void :frown: if (adviceTask == null || returnType == null || !typeof(Task).IsAssignableFrom(returnType)) { adviceTask?.Wait(); return(adviceValues.ReturnValue); } // otherwise, see if it is a Task or Task<> // Task is simple too: the advised method is a subtask, // so the advice is completed after the method is completed too if (returnType == typeof(Task)) { return(adviceTask); } // only Task<> left here // we need to create a new source and mark it as complete once the advice has completed var adviceTaskSource = TaskCompletionSource.Create(returnType.GetTaskType()); adviceTask.ContinueWith(t => ContinueTask(t, adviceTaskSource, adviceValues)); return(adviceTaskSource.Task); }