Introduction
The System.Reflection.Emit
namespace provides classes to create dynamic assemblies at runtime. It allows compilers and tools to emit MSIL, execute it and store it to a disk. Although Emit
is a powerful tool, it is also extremely hard to use.
Let us take a look at the following example, which demonstrates the "normal" way of Emit
programming:
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace EmitDemo
{
public interface IHello
{
void SayHello(string toWhom);
}
class Program
{
static void Main(string[] args)
{
AssemblyName asmName = new AssemblyName();
asmName.Name = "HelloWorld";
AssemblyBuilder asmBuilder =
Thread.GetDomain().DefineDynamicAssembly
(asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule
("HelloWorld");
TypeBuilder typeBuilder = modBuilder.DefineType(
"Hello",
TypeAttributes.Public,
typeof(object),
new Type[] { typeof(IHello) });
MethodBuilder methodBuilder = typeBuilder.DefineMethod("SayHello",
MethodAttributes.Private | MethodAttributes.Virtual,
typeof(void),
new Type[] { typeof(string) });
typeBuilder.DefineMethodOverride(methodBuilder,
typeof(IHello).GetMethod("SayHello"));
ILGenerator il = methodBuilder.GetILGenerator();
// string.Format("Hello, {0} World!", toWhom)
//
il.Emit(OpCodes.Ldstr, "Hello, {0} World!");
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Call, typeof(string).GetMethod
("Format", new Type[] { typeof(string), typeof(object) }));
// Console.WriteLine("Hello, World!");
//
il.Emit(OpCodes.Call, typeof(Console).GetMethod
("WriteLine", new Type[] { typeof(string) }));
il.Emit(OpCodes.Ret);
Type type = typeBuilder.CreateType();
IHello hello = (IHello)Activator.CreateInstance(type);
hello.SayHello("Emit");
}
}
}
using System;
using BLToolkit.Reflection;
using BLToolkit.Reflection.Emit;
namespace EmitHelperDemo
{
public interface IHello
{
void SayHello(string toWhom);
}
class Program
{
static void Main(string[] args)
{
EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
.DefineType ("Hello", typeof(object), typeof(IHello))
.DefineMethod(typeof(IHello).GetMethod("SayHello"))
.Emitter;
emit
// string.Format("Hello, {0} World!", toWhom)
//
.ldstr ("Hello, {0} World!")
.ldarg_1
.call (typeof(string), "Format", typeof(string),
typeof(object))
// Console.WriteLine("Hello, World!");
//
.call (typeof(Console), "WriteLine", typeof(string))
.ret()
;
Type type = emit.Method.Type.Create();
IHello hello = (IHello)TypeAccessor.CreateInstance(type);
hello.SayHello("C#");
}
}
}