小试Emit

.NET中的Emit,其实是个很强大的东东,它允许你在你的程序运行时,动态的生成代码。看到这里,也许大家会联想到Reflection,的确,Reflection也是我们平时用得比较多的一种技术,通过Reflection,我们能通过程序集中的元数据,动态的生成目标程序集的Instance,并执行它。而Emit的功能,恰恰和Reflection遥相呼应,前者允许我们动态的生成代码,后者允许我们动态的“查看”和运行代码。Emit和Reflection合在一起,简直就是双剑合璧,简直就是幸福的一家……难怪,微软也很邪恶的把Emit放在了System.Reflection.Emit。

其实哥平时的开发中,用得比较多的,还是Reflection(反射)了,不过早已久仰Emit的大名,又没闲暇时间来窥探一把,最近总算比较闲了,决心研究研究强大的Emit。

话不多说,代码是最有力的说明,先献上一个通过Emit动态创建并生成程序集的例子:

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace Emit_Learn
{
    class Program
    {
        static void Main(string[] args)
        {
            var name = new AssemblyName("HelloEmit");
            var assemblyBuilder =
            AppDomain.CurrentDomain.DefineDynamicAssembly(name,
            AssemblyBuilderAccess.RunAndSave); //创建程序集
              var modelBuilder = assemblyBuilder.DefineDynamicModule("HelloEmit",             "HelloEmit.dll"); //创建模块
              var typeBuilder = modelBuilder.DefineType("HelloEmit"); //定义类型
              var methodBuilder = typeBuilder.DefineMethod("Execute",                                 MethodAttributes.Public,                                 null,                                 null); //创建MethodBuilder
            var il = methodBuilder.GetILGenerator(); //获取ILGenerator,用于生成方法的IL
            il.Emit(OpCodes.Ldstr, "Hello, Emit");
            il.Emit(OpCodes.Call,                     typeof(Console).GetMethod("WriteLine",                     new Type[] { typeof(string) }));
            il.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            assemblyBuilder.Save("HelloEmit.dll"); //保存动态生成的程序集到磁盘文件

        }
    }
}

在IDE中输入以上代码,F5运行,你会发现,在你的程序的Debug目录,会生成一个HelloEmit.dll。没错,这就是我们的程序动态生成的程序集,并且它是可执行的。以上的代码,动态生成的程序集,包含一个叫HelloEmit的类,类中有一个public属性的Execute方法。方法中调用Console输出字符串:Hello,Emit

这个类,等价于如下的C#代码:

internal class HelloEmit
{
    // Methods
    public void Execute()
    {
        Console.WriteLine("Hello, Emit");
    }
}

我们也可以使用.NET Reflector一类的工具,打开生成的Dll查看,顺便验证一下。

Emit适用的场景:适用于对业务灵活性要求很高的系统,可以在运行时动态更改业务逻辑,并动态生成代码。

支持原创技术分享,据说打赏我的人,都找到了女朋友!