/// <summary> /// 建造程序运行信息 /// </summary> /// <param name="log">程序运行日志</param> /// <param name="context">方法元数据</param> public static void BuildRuningInfo(this RunningLog log, MethodAdviceContext context) { log.StartTime = DateTime.Now; log.OperatorAccount = null; }
public virtual void Advise(MethodAdviceContext context) { Console.WriteLine($"<==========before proceed {context.TargetName}==========>"); context.Proceed(); Console.WriteLine("<==========end proceed==========>"); }
public void Advise(MethodAdviceContext context) { context.Proceed(); context.ReturnValue = new IntPtr(1234); }
public void Advise(MethodAdviceContext context) { // do things you want here context.Proceed(); // this calls the original method // do other things here }
/// <summary>发生异常事件</summary> /// <param name="context">方法元数据</param> /// <param name="exception">异常实例</param> protected override void OnException(MethodAdviceContext context, Exception exception) { //抛出异常 throw new RepositoryException(exception.Message, exception); }
public abstract void Advise(MethodAdviceContext context);
public void Advise(MethodAdviceContext context) { }
public void Advise(MethodAdviceContext context) { var targetType = context.TargetMethod.DeclaringType; Assert.IsTrue(targetType.IsInterface); }
public void Advise(MethodAdviceContext context) { context.Arguments[0] = (string)context.Arguments[0] + "E"; context.Proceed(); }
/// <summary> /// 结束事务 /// </summary> /// <param name="args"></param> public void OnExit(MethodAdviceContext args) { DbPool.GetDb().EndTransaction(GetTranKey(args)); }
private string GetTranKey(MethodAdviceContext args) { return(args.TargetMethod.GetHashCode().ToString()); }
/// <summary> /// 回滚事务 /// </summary> /// <param name="args"></param> public void OnException(MethodAdviceContext args) { DbPool.GetDb().Rollback(GetTranKey(args)); }
/// <summary> /// 提交事务 /// </summary> /// <param name="args"></param> public void OnSuccess(MethodAdviceContext args) { DbPool.GetDb().Commit(GetTranKey(args)); }
/// <summary> /// 开始事务 /// </summary> /// <param name="args"></param> public void OnEntry(MethodAdviceContext args) { DbPool.GetDb().BeginTransaction(GetTranKey(args)); }
public MethodInterceptionArgs(MethodAdviceContext context) : base(context) { }
protected virtual void AdviseSync(MethodAdviceContext context, Func <object> proceed) { AdviseAsync(context, () => Task.FromResult(proceed())); }
/// <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 var advisedInterface = target as AdvisedInterface; if (advisedInterface != null) { 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 // TODO: this is actually not true, since an async method can be void :frown: 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)); }
protected abstract Task AdviseAsync(MethodAdviceContext context, Func <Task <object> > proceed);
public void Advise(MethodAdviceContext context) { MethodInterceptionArgs args = new MethodInterceptionArgs(context); OnInvoke(args); }
public void Advise(MethodAdviceContext context) { Console.WriteLine("Entry From Advice B"); context.Proceed(); Console.WriteLine("Exit From Advice B"); }
/// <summary> /// Implements advice logic. /// Usually, advice must invoke context.Proceed() /// </summary> /// <param name="context">The method advice context.</param> /// <code></code> public void Advise(MethodAdviceContext context) { context.Proceed(); context.ReturnValue = (int)context.ReturnValue + 1; }
public void Advise(MethodAdviceContext context) { Console.WriteLine("Before call."); context.Proceed(); Console.WriteLine("After call."); }
public void Advise(MethodAdviceContext context) { Console.WriteLine("before"); context.Proceed(); Console.WriteLine("after"); }
public void Advise(MethodAdviceContext call) { Count++; call.Proceed(); }
/// <summary> /// 发生异常事件 /// </summary> /// <param name="context">方法元数据</param> /// <param name="exception">异常实例</param> protected override void OnException(MethodAdviceContext context, Exception exception) { //抛出异常 throw new PresentationException(exception.Message, exception); }
/// <summary> /// 发生异常事件 /// </summary> /// <param name="context">方法元数据</param> /// <param name="exception">异常实例</param> protected override void OnException(MethodAdviceContext context, Exception exception) { base.OnException(context, exception); throw exception; }
/// <summary> /// 发生异常事件 /// </summary> /// <param name="context">方法元数据</param> /// <param name="exception">异常实例</param> protected override void OnException(MethodAdviceContext context, Exception exception) { base.OnException(context, exception); //发生异常返回统一的结果 context.ReturnValue = new StatusCodeResult(404); }
public void Advise(MethodAdviceContext context) { LastSharedAdvicesCount = ++SharedAdvicesCount[context]; context.Proceed(); }
public void Advise(MethodAdviceContext context) { context.Proceed(); }
/// <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); }