//1.构建程序集
var assemblyName = new AssemblyName("Test");
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); //定义并表示动态程序集
//2.创建模块
var mdlBldr = assemblyBuilder.DefineDynamicModule("TestMod", "Test.exe"); //用给定名称定义将保存到指定文件的持久动态访问模块,不发出符号信息
//3.定义类 ,类名为 HelloClass
var typeBldr = mdlBldr.DefineType("HelloClass",TypeAttributes.Public); //定义一个public的hello类
//4.定义类成员(方法/属性等等)
var methodBldr = typeBldr.DefineMethod("SayHelloMethod", MethodAttributes.Public | MethodAttributes.Static, null, null); //使用名称,定义一个公开的没有返回值的,没有参数的方法
//5.方法的实现
var il = methodBldr.GetILGenerator(); //获取il生成器
il.Emit(OpCodes.Ldstr," hello , world !");
/*
OpCodes枚举定义了所有可能的操作,这里用到了:
ldStr:加载一个字符串到evaluation stack。
Call:调用方法。
Ret:返回,当evaluation stack有值时会返回栈顶值。
*/
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //相当于执行 Console.WriteLine("");
il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));
il.Emit(OpCodes.Pop);//读入的值会被推送至evaluation stack,而本方法是没有返回值的,因此,需要将栈上的值抛弃
il.Emit(OpCodes.Ret);
//调用CreateType来完成类型的创建。
var helloClass = typeBldr.CreateType(); //t即为 Test类类型
assemblyBuilder.SetEntryPoint(helloClass.GetMethod("SayHelloMethod")); //将 SayHello设置为程序入口
//6.保存程序集,这里文件名字必须和模块保存到的文件一致
assemblyBuilder.Save("Test.exe");
Console.WriteLine("Hi, Dennis, a Kitty assembly has been generated for you.");
Console.ReadLine();