Esempio n. 1
0
        static public IAdvice Boundary <T>(this Advisor.IBasic basic)
            where T : Advice.IBoundary, new()
        {
            throw new NotImplementedException();

            // create a method to wrap entire call!
            // create a structure to store arguments, exception & return and implements IBefore/IAfter
            // (1) store as local the new structure
            // (2) on start instantiate Boundary with newobj if it is a class.
            // (3) call before first and give structure as argument
            // (4) try catch finally => call after in finally and check if exception != null => throw it or return value from structure!
            // voilà!



            // for async method : find AsyncMachineStructure
            // find field where IBoundary.Factory is stored.
            // replace factory! by Factory<T>

            //return new Advice((_Method, _Pointer) =>
            //{
            //    var _type = _Method.Type();
            //    var _signature = _Method.Signature();
            //    var _routine = new Closure.Routine(_Pointer, _signature, _type);
            //    var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
            //    var _body = _method.GetILGenerator();
            //    if (_type == Metadata.Void)
            //    {
            //        if (advice.Target != null) { _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target)); }
            //        _body.Emit(_signature, false);
            //        _body.Emit(OpCodes.Newobj, _routine.Constructor);
            //        _body.Emit(OpCodes.Ldftn, _routine.Method);
            //        _body.Emit(OpCodes.Newobj, Metadata<Action>.Type.GetConstructors().Single());
            //        _body.Emit(OpCodes.Call, advice.Method);
            //    }
            //    else
            //    {
            //        _body.DeclareLocal(_routine.Type);
            //        if (advice.Target != null) { _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target)); }
            //        _body.Emit(_signature, false);
            //        _body.Emit(OpCodes.Newobj, _routine.Constructor);
            //        _body.Emit(OpCodes.Stloc_0);
            //        _body.Emit(OpCodes.Ldloc_0);
            //        _body.Emit(OpCodes.Ldftn, _routine.Method);
            //        _body.Emit(OpCodes.Newobj, Metadata<Action>.Type.GetConstructors().Single());
            //        _body.Emit(OpCodes.Call, advice.Method);
            //        _body.Emit(OpCodes.Ldloc_0);
            //        _body.Emit(OpCodes.Ldfld, _routine.Value);
            //    }
            //    _body.Emit(OpCodes.Ret);
            //    _method.Prepare();
            //    return _method;
            //});
        }
Esempio n. 2
0
 /// <summary>
 /// Create an advice that runs before and after the advised method.
 /// </summary>
 /// <param name="basic">Basic</param>
 /// <param name="advice">Delegate to be invoked instead of the advised method : Action(object = [target instance of advised method call], object[] = [boxed arguments used to call advised method], Action = [delegate that invokes the advised method body])</param>
 /// <returns>Advice</returns>
 static public IAdvice Around(this Advisor.IBasic basic, Action <object, object[], Action> advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _type = _Method.Type();
         var _signature = _Method.Signature();
         var _routine = new Closure.Routine(_Pointer, _signature, _type);
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         if (_type == Metadata.Void)
         {
             if (advice.Target != null)
             {
                 _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
             }
             _body.Emit(_signature, true);
             _body.Emit(_signature, false);
             _body.Emit(OpCodes.Newobj, _routine.Constructor);
             _body.Emit(OpCodes.Ldftn, _routine.Method);
             _body.Emit(OpCodes.Newobj, Metadata <Action> .Type.GetConstructors().Single());
             _body.Emit(OpCodes.Call, advice.Method);
         }
         else
         {
             _body.DeclareLocal(_routine.Type);
             if (advice.Target != null)
             {
                 _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
             }
             _body.Emit(_signature, true);
             _body.Emit(_signature, false);
             _body.Emit(OpCodes.Newobj, _routine.Constructor);
             _body.Emit(OpCodes.Stloc_0);
             _body.Emit(OpCodes.Ldloc_0);
             _body.Emit(OpCodes.Ldftn, _routine.Method);
             _body.Emit(OpCodes.Newobj, Metadata <Action> .Type.GetConstructors().Single());
             _body.Emit(OpCodes.Call, advice.Method);
             _body.Emit(OpCodes.Ldloc_0);
             _body.Emit(OpCodes.Ldfld, _routine.Value);
         }
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
Esempio n. 3
0
 /// <summary>
 /// Create an advice that runs before the advised method.
 /// </summary>
 /// <param name="basic">Basic</param>
 /// <param name="advice">Delegate to be invoked before the advised method</param>
 /// <returns>Advice</returns>
 static public IAdvice Before(this Advisor.IBasic basic, Action advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _signature = _Method.Signature();
         var _method = new DynamicMethod(string.Empty, _Method.ReturnType, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         if (advice.Target != null)
         {
             _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
         }
         _body.Emit(OpCodes.Call, advice.Method);
         _body.Emit(_signature, false);
         _body.Emit(_Pointer, _Method.ReturnType, _signature);
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
Esempio n. 4
0
 /// <summary>
 /// Create an advice that runs before and after the advised method.
 /// </summary>
 /// <typeparam name="T">Resource to create before and dispose after method execution</typeparam>
 /// <param name="basic">Basic</param>
 /// <returns>Advice</returns>
 static public IAdvice Around <T>(this Advisor.IBasic basic)
     where T : class, IDisposable, new()
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _type = _Method.Type();
         var _signature = _Method.Signature();
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         _body.DeclareLocal(Metadata <T> .Type);
         if (_type == Metadata.Void)
         {
             _body.BeginExceptionBlock();
             _body.Emit(OpCodes.Newobj, Metadata.Constructor(() => new T()));
             _body.Emit(OpCodes.Stloc_0);
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.BeginFinallyBlock();
             _body.Emit(OpCodes.Ldloc_0);
             _body.Emit(OpCodes.Callvirt, Metadata <IDisposable> .Method(_Disposable => _Disposable.Dispose()));
             _body.EndExceptionBlock();
         }
         else
         {
             _body.DeclareLocal(_type);
             _body.BeginExceptionBlock();
             _body.Emit(OpCodes.Newobj, Metadata.Constructor(() => new T()));
             _body.Emit(OpCodes.Stloc_0);
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.Emit(OpCodes.Stloc_1);
             _body.BeginFinallyBlock();
             _body.Emit(OpCodes.Ldloc_0);
             _body.Emit(OpCodes.Callvirt, Metadata <IDisposable> .Method(_Disposable => _Disposable.Dispose()));
             _body.EndExceptionBlock();
             _body.Emit(OpCodes.Ldloc_1);
         }
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
Esempio n. 5
0
 /// <summary>
 /// Create an advice that runs before and after the advised method.
 /// </summary>
 /// <param name="basic">Basic</param>
 /// <param name="advice">Delegate to be invoked instead of the advised method : Func(object = [target instance of advised method call], object[] = [boxed arguments used to call advised method], Func() = [delegate that invokes advised method body (return boxed return value or null if return type is void)]) return boxed return value (null if return type is void)</param>
 /// <returns>Advice</returns>
 static public IAdvice Around(this Advisor.IBasic basic, Func <object, object[], Func <object>, object> advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _type = _Method.Type();
         var _signature = _Method.Signature();
         var _function = new Closure.Function(_Pointer, _signature, _type);
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         if (advice.Target != null)
         {
             _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
         }
         _body.Emit(_signature, true);
         _body.Emit(_signature, false);
         _body.Emit(OpCodes.Newobj, _function.Constructor);
         _body.Emit(OpCodes.Ldftn, _function.Method);
         _body.Emit(OpCodes.Newobj, Metadata <Func <object> > .Type.GetConstructors().Single());
         _body.Emit(OpCodes.Call, advice.Method);
         if (_type == Metadata.Void)
         {
             _body.Emit(OpCodes.Pop);
         }
         else
         {
             if (_type.IsValueType)
             {
                 _body.Emit(OpCodes.Unbox_Any, _type);
             }
             else
             {
                 _body.Emit(OpCodes.Castclass, _type);
             }
         }
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
Esempio n. 6
0
 /// <summary>
 /// Create an advice that runs after the advised method regardless of its outcome.
 /// </summary>
 /// <param name="basic">Basic</param>
 /// <param name="advice">Delegate to be invoked after the advised method</param>
 /// <returns>Advice</returns>
 static public IAdvice After(this Advisor.IBasic basic, Action advice)
 {
     return(new Advice((_Method, _Pointer) =>
     {
         var _type = _Method.ReturnType();
         var _signature = _Method.Signature();
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.DeclaringType, true);
         var _body = _method.GetILGenerator();
         _body.DeclareLocal(Metadata <bool> .Type);
         var _realized = _body.DefineLabel();
         if (_type == Metadata.Void)
         {
             _body.BeginExceptionBlock();
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.Emit(OpCodes.Ldc_I4_1);
             _body.Emit(OpCodes.Stloc_0);
             if (advice.Target != null)
             {
                 _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
             }
             _body.Emit(OpCodes.Call, advice.Method);
             _body.BeginCatchBlock(Metadata <Exception> .Type);
             _body.Emit(OpCodes.Pop);
             _body.Emit(OpCodes.Ldloc_0);
             _body.Emit(OpCodes.Brtrue, _realized);
             if (advice.Target != null)
             {
                 _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
             }
             _body.Emit(OpCodes.Call, advice.Method);
             _body.MarkLabel(_realized);
             _body.Emit(OpCodes.Rethrow);
             _body.EndExceptionBlock();
         }
         else
         {
             _body.DeclareLocal(_type);
             _body.BeginExceptionBlock();
             _body.Emit(_signature, false);
             _body.Emit(_Pointer, _type, _signature);
             _body.Emit(OpCodes.Stloc_1);
             _body.Emit(OpCodes.Ldc_I4_1);
             _body.Emit(OpCodes.Stloc_0);
             if (advice.Target != null)
             {
                 _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
             }
             _body.Emit(OpCodes.Call, advice.Method);
             _body.BeginCatchBlock(Metadata <Exception> .Type);
             _body.Emit(OpCodes.Pop);
             _body.Emit(OpCodes.Ldloc_0);
             _body.Emit(OpCodes.Brtrue, _realized);
             if (advice.Target != null)
             {
                 _body.Emit(OpCodes.Ldsfld, Advisor.Module.DefineField(advice.Target));
             }
             _body.Emit(OpCodes.Call, advice.Method);
             _body.MarkLabel(_realized);
             _body.Emit(OpCodes.Rethrow);
             _body.EndExceptionBlock();
             _body.Emit(OpCodes.Ldloc_1);
         }
         _body.Emit(OpCodes.Ret);
         _method.Prepare();
         return _method;
     }));
 }
Esempio n. 7
0
 /// <summary>
 /// After
 /// </summary>
 /// <param name="basic">Basic</param>
 /// <returns>After</returns>
 static public Advisor.Basic.IAfter After(this Advisor.IBasic basic)
 {
     return(null);
 }