在同一个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);
}
}
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);
}
}