blog.vorpal.cc

Hi! My name is David Hogue. I write code in Bend, Oregon.

January 8, 2008

Check This Out (Simple Reflection.Emit Stuff)

Filed under: — David @ 12:00 am
C#:
  1. public class HelloModifier
  2. {
  3.     public static Target CreateTarget()
  4.     {
  5.         AssemblyName assemblyName = new AssemblyName("MyDynamic");
  6.         TypeBuilder typeBuilder = AppDomain.CurrentDomain.
  7.             DefineDynamicAssembly(assemblyName,
  8.                 AssemblyBuilderAccess.Run).
  9.             DefineDynamicModule(assemblyName.Name).
  10.             DefineType("TargetOverride", TypeAttributes.Class,
  11.                 typeof(Target));
  12.         MethodBuilder hello = typeBuilder.DefineMethod("Hello",
  13.             MethodAttributes.Public | MethodAttributes.HideBySig |
  14.             MethodAttributes.NewSlot | MethodAttributes.Virtual,
  15.             CallingConventions.Standard, typeof (string),
  16.             Type.EmptyTypes);
  17.         ILGenerator il = hello.GetILGenerator();
  18.         il.Emit(OpCodes.Ldstr, "Hello, World!");
  19.         il.Emit(OpCodes.Ret);
  20.         typeBuilder.DefineMethodOverride(hello,
  21.             typeof(Target).GetMethod("Hello"));
  22.         return (Target)Activator.CreateInstance(
  23.             typeBuilder.CreateType());
  24.     }
  25. }
  26.  
  27. public class Target
  28. {
  29.     public virtual string Hello()
  30.     {
  31.         return "sorry";
  32.     }
  33. }
  34.  
  35. [TestFixture]
  36. public class NeatTests
  37. {
  38.     [Test]
  39.     public void SayHello()
  40.     {
  41.         Target target = HelloModifier.CreateTarget();
  42.         Assert.AreEqual("Hello, World!", target.Hello());
  43.     }
  44. }

OK, so it's not that revolutionary, but I've never had to dig into the Reflection.Emit namespaces before. I tried once before, but never got that far. It does seem hard to find good, useful documentation and examples on it.

This isn't really all that useful here, but I could come up with some imaginative uses for it if it was more dynamic.

Oh, and with DynamicProxy HelloModifier looks like this:

C#:
  1. public class HelloModifier
  2. {
  3.     private static readonly ProxyGenerator _generator =
  4.         new ProxyGenerator();
  5.  
  6.     public static Target CreateTarget()
  7.     {
  8.         return (Target)_generator.CreateClassProxy(
  9.             typeof(Target), new HelloInterceptor());
  10.     }
  11.  
  12.     private class HelloInterceptor : IInterceptor
  13.     {
  14.         public void Intercept(IInvocation invocation)
  15.         {
  16.             if (invocation.Method.Name == "Hello")
  17.                 invocation.ReturnValue = "Hello, World!";
  18.         }
  19.     }
  20. }

Leave a Reply