<= Home
Learning how to Emit
Just some advice if you ever want to create types on the fly during runtime.
I have been wanting to create my own proxy framework that supports aspect oriented programming for a while but was a little intimidated by the classes in System.Reflection.Emit. Actually though it’s not that hard though to get started I learned, by following these steps…
- Write some code in VB.NET or C# that you want to be able to dynamically emit during runtime.
- Compile the code and use ILDASM to look at the MSIL code
- Then mimic the MSIL code by using the classes in System.Reflection.Emit.
Example
So lets say you have an interface IHelloWorld you want to emit dynamically.
Public Interface IHelloWorld
Function GetHelloWorld() As String
End Interface
Write a class similar to what you will want to emit.
Public Class MSILCodeExample
Implements IHelloWorld
Public Function GetHelloWorld() As String Implements IHelloWorld.GetHelloWorld
Return "Hello"
End Function
End Class
And then compile the code and look at the MSIL from ILDASM.
.method public newslot strict virtual final
instance string GetHelloWorld() cil managed
{
.override CallDynamicClass.IHelloWorld::GetHelloWorld
// Code size 11 (0xb)
.maxstack 1
.locals init ([0] string GetHelloWorld)
IL_0000: nop
IL_0001: ldstr "Hello"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method MSILCodeExample::GetHelloWorld
To create this method during runtime your code would look similar to this:
Private Sub CreateHelloWorldMethod(ByVal builder As TypeBuilder)
Dim method As MethodBuilder = builder.DefineMethod("GetHelloWorld", MethodAttributes.Public, CallingConventions.Standard, GetType(String), New Type() {})
Dim il As ILGenerator = method.GetILGenerator()
Dim returnStatement As Label = il.DefineLabel()
il.DeclareLocal(GetType(String))
il.Emit(OpCodes.Nop)
il.Emit(OpCodes.Ldarg, "Hello")
il.Emit(OpCodes.Stloc_0)
il.Emit(OpCodes.Br_S, returnStatement)
il.MarkLabel(returnStatement)
il.Emit(OpCodes.Ldloc_0)
il.Emit(OpCodes.Ret)
End Sub