Click here to Skip to main content
11,922,587 members (30,395 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


6 bookmarked

Generating Assemblies at runtime using IL emit

, 2 Jul 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
How to generate assemblies at runtime using IL emit.

Let’s start with a bold statement: IL rocks! Fair enough, but can it do Jazz or Mozart too? Turns out, yes it can :)

While thinking of a way to magically create an instance out of an interface for my little MData project, I figured i’d have to go with IL generating such a class. It seemed like a daunting task at first. Really, look at this code:

Offset OpCode 
0 ldnull 
1 ldarg.0 
2 ldc.i4.2 
3 newarr System.Object
8 stloc.0 
9 ldloc.0 
10 ldc.i4.0 
11 ldarg.1 
12 stelem.ref 
13 ldloc.0 
14 ldc.i4.1 
15 ldarg.2 
16 stelem.ref 
17 ldloc.0 
18 call System.String System.String::Format(System.IFormatProvider,System.String,System.Object[])
23 ret

Can you guess which method this is? probably not, well here it is:

public static string Format(string format, object arg0, object arg1)
    return Format(null, format, new object[] { arg0, arg1 });

If you’ve never really looked into IL (or MSIL) this code may seem very hard to understand. Very handy tools to look at the IL code of a given .Net method, are ILSpy (free), Reflector (in combination with Reflexil) or Graywolf (free). These tools let you compare the classic C#/VB.NET code to the compiled IL code. This is the best way to ‘learn’ IL.

Generating a dynamic assembly at runtime

This goes just one step further then just looking at IL code, this is actually writing IL code. While it is not possible to alter existing Assemblies (not in my knowledge), it is certainly possible to create a new one. This is used in several popular frameworks which support creating proxy classes, ducktyping etc. The key here is to *not* use the default System.Reflection.Emit namespace :) . I personally don’t like the structure and approach in the standard BCL, instead I love to use BLToolkit from Igor Tkachev. It allows me to create a ‘Hello world’ example using a very natural flow:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
.DefineType ("Hello", typeof(object), typeof(IHello))

// string.Format("Hello, {0}!", toWhom)
.ldstr ("Hello, {0}!")
.call (typeof(string), "Format", typeof(string), typeof(object))

// Console.WriteLine("Hello, World!");
.call (typeof(Console), "WriteLine", typeof(string))

And that’s it, we created a new assembly with one type containing one method. As you can see we can define a baseclass for the type, we could also add which interfaces to implement etc.

TIP: To put a certain class in a namespace, define the name as follows: Path.Of.Your.Namespace.[GeneratedTypeName], this will trigger the emit system to extract the namespace from the class name.

Now let’s try to make a working example of a ducktyping system. the purpose of our little library will be to cast any given class to a interface it doesn’t explicitly implement. Something like this:

class Program
    static void Main(string[] args)
        A a = new A();
        ITest aAsITest = a.Duck<ITest>();

public class A
    string Data { get; set; }

    public void Method()
public interface ITest
    string Data { get; set; }
    void Method();

Notice how class A does not implement ITest, after ‘ducking’ however, I can have an instance of ITest working on the A instance. The first step would be creating some kind of workflow and scope for this project:

  • The targetType should have all members of the interface defined as public
  • We will not take into account that only a subset of members is implemented by the targetType, so only one on one matches
  • We will map methods, properties and events.

First step is actually creating an ‘AssemblyBuilder’ from the BLToolkit:

static ClassFactory()
    _assemblyBuilder = new AssemblyBuilderHelper(GetGeneratedAssemblyPath());

private static string GetGeneratedAssemblyPath()
    return @".\Duck.Tape.Generated.dll";

That was easy! Now here is the flow of creating all methods, properties and event on the newly generated type:

var typeBuilder = _assemblyBuilder.DefineType(GetGeneratedTypeName(), typeof(object), InterfaceToImplement);

//create private field
var classToWrapField = typeBuilder.DefineField(GetGeneratedToWrapFieldName(), ClassToWrap, FieldAttributes.Private);

//map interface members
MapInterfaceProperties(classToWrapField, typeBuilder);
MapInterfaceEvents(classToWrapField, typeBuilder);
MapInterfaceMethods(classToWrapField, typeBuilder);

//define constructor
DefineConstructor(classToWrapField, typeBuilder);

As you can see, we have a clear overview of what is happening during the creation of our new Type. This is very important when dealing with the whole Emit thing. Keep things as simple as possible, and please don’t create methods larger then 20-25 lines. It can get real messy, real fast.

Now for some IL magic, let’s look at how the constructor is defined:

private void DefineConstructor(FieldInfo classToWrapField, TypeBuilderHelper typeBuilder)
        //take an instance of 'ClassToWrap' as constructor parameter
        //: base()
        //this.[fieldName] = [constructorParameter]

If you are interested in this library, please download/fork it here!

Please don’t send me e-mails that is doesn’t work for you, just open an issue on github, or create a pull request and solve it yourself ;)


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Pieter Van Parys
Software Developer
Belgium Belgium
LinkedIn Profile

I maintain a blog at

You may also be interested in...

Comments and Discussions

GeneralFormatting Issues Pin
Tim Corey2-Jul-12 3:50
memberTim Corey2-Jul-12 3:50 
GeneralRe: Formatting Issues Pin
Pieter Van Parys2-Jul-12 3:59
memberPieter Van Parys2-Jul-12 3:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.151125.1 | Last Updated 2 Jul 2012
Article Copyright 2012 by Pieter Van Parys
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid