tags:

views:

92

answers:

4

I have a .NET assembly which has defined a type T at compile time, and I have instantiated an object my_t as an instance of this type.

I am wondering if it is possible in .NET to use the runtime compiler services to re-compile this class, then load the new class definition into the currently executing assembly, so when I call methods off of my_t, they will use the new code.

I am not changing the signatures of any of the methods, just the method bodies.

Any .NET gurus out there know if this is possible? Thanks in advance for any help!

+2  A: 

A .NET object can't change type at runtime; it's a fundamental assumption in the CLR.

A few suggestions:

  1. Write the code for T to forward calls to the right type as appropriate. It can forward to a type that gets compiled at runtime if you want to.
  2. Use some kind of aspect-orientated or dynamic proxy framework to automate (1) for you
  3. If this kind of forwarding isn't suitable, I believe there is a .NET profiling API available to native that lets you intercept the JIT process. All I know of this is that tools like NCover are able to inject their own machine code this way.
Tim Robinson
I think your suggest #1 is very promising - I have a prototype working now. One question is whether calling my_t.GetType().GetMethod("my_method_name") is a major performance hit versus calling, say, my_t.my_method_name directly. Any idea?
Mike
It's a dreadful performance hit. Take a look at ashish.s's Castle Dynamic Proxy suggestion.
Tim Robinson
A: 

To expand upon my comment:

public class Base
{
    public virtual void Method()
    {

    }
}

public class Sub : Base
{
    public override void Method()
    {

    }
}

public void DoStuff<T>() where T : Base, new()
{
    var instance = new T();
    instance.Method();
}
ChaosPandion
+3  A: 

I'm not sure that is possible, but if it is, it sounds like an awfully messy solution.

Use a plugin architecture, so you can dynamically compile your generated plugin, inheriting from your plugin interface and simply load that type from your newly created assembly and inject it into your plugin container.

Wim Hollebrandse
+1. Take a look at http://www.codeplex.com/MEF
TrueWill
+2  A: 

you can use castle dynamic proxy to create a proxy of your class. The proxy is a new type that would let you inject new implementation, but anything that you want to inject would have to declared as virtual.

Interesting - I assume you're talking about http://www.castleproject.org/dynamicproxy/index.html - have you used this? How is performance impacted, if you happen to know? Thx!
Mike
I have used it in one my projects, the performance impact should stabilize, since its actually generating code and compiling it into an assembly for your types.