.net动态构建程序集
关于动态构建程序集,是前不久发现公司的WebService框架中,用到了一个类ILGenerator,翻查了MSDN,原来是用来生成MSIL指令的,然后再继续探究,发现可以用ILGnerator在运行时,动态创建程序集,类,方法。下面就简单举一个例子。
假如我们的程序中有这样的一个类,
public class Test
{
public void Output(string str)
{
Console.WriteLine(str);
}
}
我们可以用Reflector,反编译出Output方法相应的IL代码:
.method public hidebysig instance void Output(string str) cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldarg.1
L_0002: call void [mscorlib]System.Console::WriteLine(string)
L_0007: nop
L_0008: ret
}
然后根据这个IL代码,动态创建程序集。
--定义一个程序集名:
AssemblyName asm = new AssemblyName();
asm.Name = "DynamicInvokeTest.dll";
--获取当前应用程序域:
AppDomain appdomain = System.Threading.Thread.GetDomain();
--定义程序集
AssemblyBuilder abuilder = appdomain.DefineDynamicAssembly(asm, AssemblyBuilderAccess.RunAndSave);
--定义模块
ModuleBuilder mbuilder = abuilder.DefineDynamicModule("DynamicInvokeTest","DynamicInvokeTest.dll");
--定义类
TypeBuilder theClass = mbuilder.DefineType("DynamicInvokeTest.Test", TypeAttributes.Public | TypeAttributes.Class);
--定义方法或者字段
--如果方法有参数或者返回值的,应先定义参数或者返回值类型,根据上面的例子,需要传入string 类型的参数,所以定义如--下:
Type[] param = new Type[1];//定义方法的参数
param[0] = typeof(System.String);
MethodBuilder methodBuilder = theClass.DefineMethod("Output", MethodAttributes.Public, null, param);
--然后根据上面IL代码,定义方法体
ILGenerator gen = methodBuilder.GetILGenerator();
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new Type[]{typeof(string)}));
gen.Emit(OpCodes.Ret);
--最后调用我们所创建的程序集
--创建类型
Type TestClass = theClass.CreateType();
--创建对象
object TestInst = Activator.CreateInstance(TestClass );
--调用方法
object[] args = new object[] { "Dynamic Test" };
TestClass .InvokeMember("Output", BindingFlags.InvokeMethod, null, TestInst , args);
整个过程就是这样,这只是简单例子,我们可以在实践中,构建更加复杂代码。。。