In my previous article I explained about how to invoke metadata by using System.Reflection namespace. Today we will discuss how to create types dynamically by using System.Reflection.Emit namespace.
System.Reflection.Emit namespace is used to create C# types like Classes, Properties, and Variables….etc dynamically. System.Reflection.Emit namespace contains many classes which are useful to create types dynamically.
Open Microsoft Visual Studio 2013 => Create C# Console Application and name it as CreateTypesDynamically. Create assembly, class and method dynamically as shown below.
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace CreateTypesDynamically
{
class Program
{
static void Main(string[] args)
{
AssemblyName aName = new AssemblyName("DynamicAssembly");
AppDomain appDomain = Thread.GetDomain();
AssemblyBuilder aBuilder = appDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder mBuilder = aBuilder.DefineDynamicModule("DynamicModule");
TypeBuilder typeBuilder = mBuilder.DefineType("DynamicClass", TypeAttributes.Public);
Type[] tparams = { typeof(System.Int32), typeof(System.Int32) };
MethodBuilder mSub = typeBuilder.DefineMethod("DynamicMethod", MethodAttributes.Public, typeof(System.Int32), tparams);
ILGenerator ilGenerator = mSub.GetILGenerator();
ilGenerator.DeclareLocal(typeof(System.Single));
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Ldarg_2);
ilGenerator.Emit(OpCodes.Sub_Ovf);
ilGenerator.Emit(OpCodes.Conv_R4);
ilGenerator.Emit(OpCodes.Stloc_0);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
Type thistype = typeBuilder.CreateType();
MethodInfo info = thistype.GetMethod("DynamicMethod", BindingFlags.Instance | BindingFlags.Public);
object thisObj = Activator.CreateInstance(thistype);
object result = info.Invoke(thisObj, BindingFlags.Public | BindingFlags.CreateInstance, null, new object[] { 200, 100 }, Thread.CurrentThread.CurrentCulture);
Console.WriteLine("Difference between 200 and 100 : {0}", result);
Console.ReadLine();
}
}
}
As shown above AssemblyName class used to create assembly dynamically, TypeBuilder is used to create the class and MethodBuilder is used to create the method. Once method created, invoke method by using System.Reflection namespace as explained in my previous article.