示例#1
0
 /// <summary>
 /// Create an advice that runs before and after the advised method.
 /// </summary>
 /// <param name="linq">Linq</param>
 /// <param name="advice">Delegate used to produce an expression of code to be invoked instaed of the advised method : Func(Expression = [expression of target instance of advised method call], IEnumerable(Expression) = [enumerable of expression of argument used to call advised method], Expression = [expression of advised method body]) return an expression to invoke instead of the advised method</param>
 /// <returns>Advice</returns>
 static public IAdvice Around(this Advisor.ILinq linq, Func <Expression, IEnumerable <Expression>, Expression, Expression> advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _type = _Method.Type();
         var _signature = _Method.Signature();
         var _parameters = new Collection <ParameterExpression>(_signature.Select(_Type => Expression.Parameter(_Type)).ToArray());
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         _body.Emit(_signature, false);
         _body.Emit(_Pointer, _type, _signature);
         _body.Emit(OpCodes.Ret);
         var _advice = _signature.Instance == null ? advice(null, _parameters, Expression.Call(_method, _parameters)) : advice(_parameters[0], _parameters.Skip(1), Expression.Call(_method, _parameters));
         if (_advice == null)
         {
             return null;
         }
         _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         _body = _method.GetILGenerator();
         _body.Emit(_signature, false);
         _body.Emit(OpCodes.Call, Expression.Lambda(_advice, _parameters).CompileToMethod());
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
示例#2
0
 /// <summary>
 /// Create an advice that runs after the advised method regardless of its outcome.
 /// </summary>
 /// <param name="linq">Linq</param>
 /// <param name="advice">Delegate used to produce an expression of code to be invoked after the advised method : Func(Expression = [expression of target instance of advised method call], IEnumerable(Expression) = [enumerable of expression of argument used to call advised method]) return an expression(void) of code to invoke after the advised method</param>
 /// <returns>Advice</returns>
 static public IAdvice After(this Advisor.ILinq linq, Func <Expression, IEnumerable <Expression>, Expression> advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _signature = _Method.Signature();
         var _parameters = new Collection <ParameterExpression>(_signature.Select(_Type => Expression.Parameter(_Type)).ToArray());
         var _advice = _signature.Instance == null ? advice(null, _parameters) : advice(_parameters[0], _parameters.Skip(1));
         if (_advice == null)
         {
             return null;
         }
         if (_advice.Type != Metadata.Void)
         {
             throw new NotSupportedException();
         }
         var _type = _Method.ReturnType();
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         if (_type == Metadata.Void)
         {
             _body.BeginExceptionBlock();
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.BeginFinallyBlock();
             _body.Emit(_signature, false);
             _body.Emit(OpCodes.Call, Expression.Lambda(_advice, _parameters).CompileToMethod());
             _body.EndExceptionBlock();
         }
         else
         {
             _body.DeclareLocal(_type);
             _body.BeginExceptionBlock();
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.Emit(OpCodes.Stloc_0);
             _body.BeginFinallyBlock();
             _body.Emit(_signature, false);
             _body.Emit(OpCodes.Call, Expression.Lambda(_advice, _parameters).CompileToMethod());
             _body.EndExceptionBlock();
             _body.Emit(OpCodes.Ldloc_0);
         }
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
示例#3
0
 /// <summary>
 /// Create an advice that runs after the advised method regardless of its outcome.
 /// </summary>
 /// <param name="linq">Linq</param>
 /// <param name="advice"></param>
 /// <returns>Advice</returns>
 static public IAdvice After(this Advisor.ILinq linq, Expression advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _signature = _Method.Signature();
         if (advice == null)
         {
             return null;
         }
         if (advice.Type != Metadata.Void)
         {
             throw new NotSupportedException();
         }
         var _type = _Method.ReturnType();
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         if (_type == Metadata.Void)
         {
             _body.BeginExceptionBlock();
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.BeginFinallyBlock();
             _body.Emit(OpCodes.Call, Expression.Lambda(advice).CompileToMethod());
             _body.EndExceptionBlock();
         }
         else
         {
             _body.DeclareLocal(_type);
             _body.BeginExceptionBlock();
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.Emit(OpCodes.Stloc_0);
             _body.BeginFinallyBlock();
             _body.Emit(OpCodes.Call, Expression.Lambda(advice).CompileToMethod());
             _body.EndExceptionBlock();
             _body.Emit(OpCodes.Ldloc_0);
         }
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
示例#4
0
 /// <summary>
 /// Create an advice that runs before the advised method.
 /// </summary>
 /// <param name="linq">Linq</param>
 /// <param name="advice">Expression of code to be invoked before the advised method</param>
 /// <returns>Advice</returns>
 static public IAdvice Before(this Advisor.ILinq linq, Expression advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _signature = _Method.Signature();
         if (advice == null)
         {
             return null;
         }
         var _type = _Method.ReturnType();
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         _body.Emit(OpCodes.Call, Expression.Lambda(advice).CompileToMethod());
         _body.Emit(_signature, false);
         _body.Emit(_Pointer, _type, _signature);
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
示例#5
0
 /// <summary>
 /// After
 /// </summary>
 /// <param name="linq">Linq</param>
 /// <returns>After</returns>
 static public Advisor.Linq.IAfter After(this Advisor.ILinq linq)
 {
     return(null);
 }