Reflection.Emit的使用场景、工具包及示例总结

简介: 最近处理一个业务需要动态的生成一些业务模型和库,使用到了Emit的处理,相关的资料整理一下供参考。 Reflection.Emit目的 使用的场景: 应用中自定义一个自己的语言 运行中动态的创建类型、模块等,同时又需要提高效率(可以动态编译一次,然后就不用再处理了) 延迟绑定对象的使用,在和Office这类的软件时会用到 动态插件系统等 … System.

 最近处理一个业务需要动态的生成一些业务模型和库,使用到了Emit的处理,相关的资料整理一下供参考。

Reflection.Emit目的

使用的场景:

  • 应用中自定义一个自己的语言

  • 运行中动态的创建类型、模块等,同时又需要提高效率(可以动态编译一次,然后就不用再处理了)

  • 延迟绑定对象的使用,在和Office这类的软件时会用到

  • 动态插件系统等

System.Reflection.Emit主要的类:

  • AssemblyBuilder 应用的初始点,反射发出代码、创建动态Modules

  • ModuleBuilder 添加类型如类、结构等

  • ILGenerator.OpCodes 生成 MSIL 指令

反射发出开发时可用的工具包

直接使用框架基础类开发:比较繁琐,对于比较简单的,可以使用http://reflectoraddins.codeplex.com/wikipage?title=ReflectionEmitLanguage&referringTitle=Home 这个Reflector插件,查看类、方法和组件对应的代码,可以处理一些比较简单的应用

使用封装类进行开发:如下的形式

      RunSharp:提供了一个类似C#对应语言的包装形式,熟悉后可很快应用,而且编写的代码页比较少

      BLToolkit:类似IL的形式进行使用,需要对IL熟悉后才能使用

 

下文对三种形式一个举例,可以根据实际情况选择

 

Reflection.Emit的例子

using System;

using System.Runtime;

using System.Reflection;

using System.Reflection.Emit;

 

public class class1

{

    public static void Main()

    {

        AppDomain ad = AppDomain.CurrentDomain;

        AssemblyName am = new AssemblyName();

        am.Name = "TestAsm";

        AssemblyBuilder ab = ad.DefineDynamicAssembly(am, AssemblyBuilderAccess.Save);

        ModuleBuilder mb = ab.DefineDynamicModule("testmod", "TestAsm.exe");

        TypeBuilder tb = mb.DefineType("mytype", TypeAttributes.Public);

        MethodBuilder metb = tb.DefineMethod("hi", MethodAttributes.Public |

        MethodAttributes.Static, null, null);

        ab.SetEntryPoint(metb);

 

        ILGenerator il = metb.GetILGenerator();

        il.EmitWriteLine("Hello World");

        il.Emit(OpCodes.Ret);

        tb.CreateType();

        ab.Save("TestAsm.exe");

    }

}

 

RunSharp

http://www.codeproject.com/KB/dotnet/runsharp.aspx  简要的说明

http://code.google.com/p/runsharp/ 代码下载

A simple hello world example in C#

public class Test

{

   public static void Main(string[] args)

   {

      Console.WriteLine("Hello " + args[0]);

   }

}

can be dynamically generated using RunSharp as follows:

AssemblyGen ag = new AssemblyGen("hello.exe");

TypeGen Test = ag.Public.Class("Test");

{

   CodeGen g = Test.Public.Static.Method(typeof(void), "Main", typeof(string[]));

   {

      Operand args = g.Param(0, "args");

      g.Invoke(typeof(Console), "WriteLine", "Hello " + args[0] + "!");

   }

}

ag.Save();

 

Bltoolkit

http://www.bltoolkit.net/

http://www.bltoolkit.net/Doc.EmitHelloWorld.ashx  这个工具包关于反射发出的使用例子

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
 
  
using System;

using NUnit.Framework;

using BLToolkit.Reflection;

using BLToolkit.Reflection.Emit;



namespace Examples.Reflection.Emit

{

[TestFixture]

public class HelloWorld

{

public interface IHello

{

void SayHello( string toWhom);

}



[Test]

public void Test()

{

EmitHelper emit
= new AssemblyBuilderHelper( " HelloWorld.dll " )

.DefineType (
" Hello " , typeof ( object ), typeof (IHello))

.DefineMethod(
typeof (IHello).GetMethod( " SayHello " ))

.Emitter;



emit

// string.Format("Hello, {0}!", toWhom)

//

.ldstr (
" Hello, {0}! " )

.ldarg_1

.call (
typeof ( string ), " Format " , typeof ( string ), typeof ( object ))



// Console.WriteLine("Hello, World!");

//

.call (
typeof (Console), " WriteLine " , typeof ( string ))

.ret()

;



Type type
= emit.Method.Type.Create();



IHello hello
= (IHello)TypeAccessor.CreateInstance(type);



hello.SayHello(
" World " );

}

}

}

 

 

 

相关文章
|
6月前
|
Go
Go 1.18 新增三大功能之一“泛型”怎么使用?
Go 1.18 新增三大功能之一“泛型”怎么使用?
33 0
|
11月前
|
存储
基于boost的bind与function的一个简单示例消息处理框架
前两年开始接触boost,boost库真是博大精深;今天简单介绍一下boost中之前用到的的bind与function,感觉挺实用的,分享给大家,我对boost用的也不多,让大家见笑了。
64 0
|
Java
Java常用API---Runtime(消息机制)含代码例子
私有化构造方法,不能被实例化
140 0
Java常用API---Runtime(消息机制)含代码例子
|
Java API C#
C#反射与特性(十):EMIT构建代码
C#反射与特性(十):EMIT构建代码
226 0
|
Java API Kotlin
【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
185 0
【Kotlin】apply 内联扩展函数 ( apply 函数原型 | apply 函数示例 | Kotlin 调用 Java API )
|
JavaScript Java Serverless
表格存储触发函数计算示例之 Nodejs/Php/Java/C# Runtime
创建Table Store触发器,能够实现Table Store Stream和函数计算的自动对接,从而实现OTS数据发生变更时候定制化的自动处理。本教程作为补充,通过代码示例说明在其他runtime下怎么玩转Table Store触发器。
3669 0
|
Web App开发 存储 NoSQL
表格存储触发java runtime的函数计算处理示例教程
函数计算(Function Compute)是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。通过创建Table Store触发器,能够实现Table Store Stream和函数计算的自动对接,从而实现OTS数据发生变更时候定制化的自动处理,本教程展示java版的代码示例。
2800 0
|
JSON JavaScript Java
用 Rhino/Nashorn 代替第三方 JSON 转换库(第三版)
无须其他第三方包,只是依赖于 Java 自带的 JVM 自带的 Rhino/Nashorn 引擎提供 js/json 的服务。主要的两个类是 JsEngineWrapper、JsonHelper,它们的继承关系是 JsEngineWrapper 派生了 JsonHelper。
1105 0