Question

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 inject 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 must be able to do this at runtime, so compile-time and post-processing methods are out of the question.

My initial approach used Delegate.Combine() to add the prologue and epilogue methods to the Foo delegate. Alas, this won't work as it munges 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 the MethodInfo for FooImplementation, get its MethodBody, convert that to a DynamicMethod and inject my try-finally block into that.

Unfortunately, I have absolutely no idea how to do this. Anyone willing to lend a hand? Or do you have another (preferably simpler) idea?

Edit: the use-case here is debugging an OpenGL binding (http://www.opentk.com). We have to inject 2226 methods with wildly different parameters, so a general approach is necessary.

Was it helpful?

Solution 6

What I finally ended up doing was to implement my own rewriting solution using Mono.Cecil. Simple, fast and it works fine. Unfortunately, this has to be done as a post-build event, so this is not actually runtime code injection.

OTHER TIPS

You could use Expressions.

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();

This way, you can build the expressions for the prologue and epilogue in runtime.

Note sure what you're trying to do, but if it's simply redirecting the FooImplementation that's pointed to at the Foo Field then you can simply do:

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");
    }
}

Of course the Inject doesn't have to be in the same class, however if the field/property isn't publicly accessible you'll have to use Reflection to do it, still not that hard though.

Have you considered using something like: Postsharp? http://www.sharpcrafters.com/postsharp

or Enterprise Library policy Injection? http://msdn.microsoft.com/en-us/library/ff650672.aspx

or even Mono.Cecil? http://www.mono-project.com/Cecil

TypeMock also maybe a viable solution to your issue: http://www.typemock.com/

You could also use the RealProxy class (http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspx ) to generate your own proxy at runtime that will first call your injected code and then call the actual method.

You can also try out CInject on codeplex to inject code into managed code (C# or VB.NET) with great ease.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top