static private Advisor Value(this Advisor.After.IReturning @this, Action <MethodBuilder> advise) { if (@this.After.Generator.Method.ReturnType() == Metadata.Void) { return(new Advisor(Advisor.Null)); } var _signature = @this.After.Generator.Method.GetParameters().Select(_Parameter => _Parameter.ParameterType).ToArray(); return(@this.After.Generator.Create((_Type, _Instance, _Arguments) => { var _advice = _Type.DefineMethod("<Advice>", MethodAttributes.Static | MethodAttributes.Private, CallingConventions.Standard, Metadata.Void, (@this.After.Generator.Method.IsStatic ? _signature : new Type[] { @this.After.Generator.Method.DeclaringType }.Concat(_signature)).Concat(new Type[] { @this.After.Generator.Method.ReturnType() }).ToArray()); _advice.DefineGenericParameters("T"); advise(_advice); var _method = _Type.DefineMethod("IAdvice.Return", MethodAttributes.Private | MethodAttributes.Virtual, CallingConventions.HasThis); var _genericity = _method.DefineGenericParameters("T")[0]; _method.SetReturnType(Metadata.Void); _method.SetParameters(new Type[] { _genericity.MakeByRefType() }); var _body = _method.GetILGenerator(); if (_Instance != null) { _body.Emit(OpCodes.Ldarg_0); _body.Emit(OpCodes.Ldfld, _Instance); } foreach (var _argument in _Arguments) { _body.Emit(OpCodes.Ldarg_0); _body.Emit(OpCodes.Ldfld, _argument); } _body.Emit(OpCodes.Ldarg_1); _body.Emit(OpCodes.Ldobj, _genericity); _body.Emit(OpCodes.Call, _advice.MakeGenericMethod(_genericity)); _body.Emit(OpCodes.Ret); _Type.DefineMethodOverride(_method, Metadata <IAdvice> .Method(_IAdvice => _IAdvice.Return(ref Metadata <object> .Value)).GetGenericMethodDefinition()); })); }
static public Advisor Value(this Advisor.After.IReturning @this, Action <ILGenerator> advise) { if (@this.After.Generator.Method.ReturnType() == Metadata.Void) { return(new Advisor(Advisor.Null)); } return(@this.Value(new Action <MethodBuilder>(_Method => { var _body = _Method.GetILGenerator(); advise(_body); _body.Emit(OpCodes.Ret); }))); }
static public Advisor Value(this Advisor.After.IReturning @this, Func <Advisor.Execution.Returning.Value, Expression> advise) { if (@this.After.Generator.Method.ReturnType() == Metadata.Void) { return(new Advisor(Advisor.Null)); } var _signature = @this.After.Generator.Method.GetParameters().Select(_Parameter => Expression.Parameter(_Parameter.ParameterType)); var _return = Expression.Parameter(@this.After.Generator.Method.ReturnType()); return(@this.Value(new Action <MethodBuilder>(_Method => { if (@this.After.Generator.Method.IsStatic) { Expression.Lambda(advise(new Advisor.Execution.Returning.Value(@this.After.Generator.Method, null, new Collection <Expression>(_signature), _return)), _signature.Concat(new ParameterExpression[] { _return })).CompileToMethod(_Method); } else { var _instance = Expression.Parameter(@this.After.Generator.Method.DeclaringType); Expression.Lambda(advise(new Advisor.Execution.Returning.Value(@this.After.Generator.Method, _instance, new Collection <Expression>(_signature), _return)), new ParameterExpression[] { _instance }.Concat(_signature).Concat(new ParameterExpression[] { _return })).CompileToMethod(_Method); } }))); }
static public Advisor Value(this Advisor.After.IReturning @this, Action advice) { return(@this.Value(Expression.Call(Expression.Field(null, Aspect.Module.DefineField(advice)), Metadata <Action> .Method(_Action => _Action.Invoke())))); }
static public Advisor Value(this Advisor.After.IReturning @this, Expression advice) { return(@this.Value(_Execution => advice)); }