System.Reflection.Emit的一个很重要的发现.

在同一个ModuleBuilder里, DefineType并且CreateType之后, 是可以继续DefineType的..
这样可以防止编译多次代码导致的AssemblyBuilder过多的问题. 现在只需要1个AssemblyBuilder就够了.
这个发现对于WEB框架非常有意义. 因为WEB框架包含大量的脚本文件. 有了这个特征, 脚本文件可以很放心地分开来编译了
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;


static public class EmitTest
{
static public void Go()
{
AssemblyBuilder asm
= AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("EmitTest"), AssemblyBuilderAccess.Run);
ModuleBuilder mdl
=asm.DefineDynamicModule("EmitTestModule");

RunType(mdl,
"Type1", "Method1", "Hello");
RunType(mdl,
"Type2", "Method2", "World");
}

private static void RunType(ModuleBuilder mdl,string typename
,
string methodname,string writestring)
{
TypeBuilder t1
= mdl.DefineType(typename);
MethodBuilder mb1
= t1.DefineMethod(methodname
, MethodAttributes.Static
| MethodAttributes.Public, typeof(void), new Type[] { });
ILGenerator g1
= mb1.GetILGenerator();
g1.Emit(OpCodes.Ldstr, writestring);
g1.Emit(OpCodes.Call,
typeof(EmitTest).GetMethod("WriteLine"));
MethodInfo mi1
= t1.CreateType().GetMethod(methodname);
mi1.Invoke(
null, null);
}

[System.Runtime.CompilerServices.MethodImpl(
System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static public void WriteLine(string str)
{
MethodBase caller
=new System.Diagnostics.StackFrame(1).GetMethod();
Console.WriteLine(caller.DeclaringType.Assembly.FullName);
Console.WriteLine(str);
}
}
 
 
posted @ 2011-06-22 13:24  Parallet  阅读(949)  评论(1)    收藏  举报