Implementing runtime code with DynamicMethod?

Consider the following trivial code:

using System;   
class Test
{
    delegate int FooDelegate(int i);
    FooDelegate Foo = FooImplementation;
    static int FooImplementation(int i)
    {
        return i + 1;
    }

    public static void Main()
    {
         Foo(1);
    }
}

What I would like to do is insert some debugging code into the Foo delegate, which would be equivalent:

FooDelegate Foo = delegate(int i)
{
    try
    {
        DebugPrologue();
        return FooImplementation(i);
    }
    finally
    {
        DebugEpilogue();
    }
};

The twist is that I should be able to do this at runtime, so compilation and post-processing methods are out of the question.

My initial approach uses Delegate.Combine () to add prolog and epilog methods to the Foo delegate. Alas, this will not work, since it returns return values.

My current idea is to use System.Reflection.Emit and DynamicMethod as a potential solution. As far as I can tell, I need to get MethodInfo for FooImplementation, get its MethodBody, convert it to DynamicMethod and insert a try-finally block in it.

, , . , ? ( ) ?

: OpenGL (http://www.opentk.com). 2226 , .

+5
6

Mono.Cecil. , . , , .

0

.

var param = Expression.Parameter(typeof(int), "i");

Foo = Expression.Lambda(
         Expression.TryFinally(
            Expression.Block(
               <expression for DebugPrologue>,
               Expression.Invoke(<expression for FooImplementation>, param)),
            <expression for DebugEpilogue>),
         param)
      .Compile();

, .

+3

, , FooImplementation, Foo, :

class Test
{
    delegate int FooDelegate(int i);
    static FooDelegate Foo = FooImplementation;

    static int FooImplementation(int i)
    {
        return i + 1;
    }

    public static void Main()
    {
        Inject();
        Foo(1);
    }


    public static void Inject()
    {
        var oldImpl = Foo;

        Foo = i =>
            {
                try
                {
                    BeginDebug();
                    return oldImpl(i);
                }
                finally
                {
                    EndDebug();
                }
            };
    }

    public static void BeginDebug()
    {
        Console.WriteLine("Begin Foo");
    }

    public static void EndDebug()
    {
        Console.WriteLine("End Foo");
    }
}

, Inject , field/public , Reflection, , .

0

TypeMock : http://www.typemock.com/

RealProxy (http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspx), - , , .

0

CInject , (# VB.NET).

0

All Articles