[ Team LiB ] Previous Section Next Section

13.8 Creating New Types at Runtime

The System.Reflection.Emit namespace contains classes that can create entirely new types at runtime. These classes can define a dynamic assembly in memory, define a dynamic module in the assembly, define a new type in the module, including all its members, and emit the MSIL opcodes needed to implement the application logic in the members.

Here is an example that creates and uses a new type called HelloWorld with a member called SayHello:

using System;
using System.Reflection;
using System.Reflection.Emit;
public class Test
{
  static void Main( )
  {
    // Create a dynamic assembly in the current AppDomain
    AppDomain ad = AppDomain.CurrentDomain;
    AssemblyName an = new AssemblyName( );
    an.Name = "DynAssembly";
    AssemblyBuilder ab = 
      ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
    
    // Create a module in the assembly & a type in the module
    ModuleBuilder modb = ab.DefineDynamicModule("DynModule");
    TypeBuilder tb = modb.DefineType("AgentSmith", 
                                     TypeAttributes.Public);
 
    // Add a SayHello member to the type 
    MethodBuilder mb = tb.DefineMethod("SayHello",        
                                       MethodAttributes.Public,
                                       null, null);
                                        
    // Generate the MSIL for the SayHello Member
    ILGenerator ilg = mb.GetILGenerator( );
    ilg.EmitWriteLine("Never send a human to do a machine's job.");
    ilg.Emit(OpCodes.Ret);
  
    // Finalize the type so we can create it
    tb.CreateType( );
  
    // Create an instance of the new type
    Type t = ab.GetType("AgentSmith");
    object o = Activator.CreateInstance(t);
    
    // Prints "Never send a human to do a machine's job."
    t.GetMethod("SayHello").Invoke(o, null);
  }
}

A common example using Reflection.Emit is the regular expression support in the FCL, which can emit new types that are tuned to search for specific regular expressions, eliminating the overhead of interpreting the regular expression at runtime.

Other uses of Reflection.Emit in the FCL include dynamically generating transparent proxies for remoting and generating types that perform specific XSLT transforms with the minimum runtime overhead.

    [ Team LiB ] Previous Section Next Section