.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);

 整个过程就是这样,这只是简单例子,我们可以在实践中,构建更加复杂代码。。。

posted @ 2010-01-07 10:19  桑叶舟  阅读(387)  评论(0编辑  收藏  举报