BLToolkit : Reflection.Emit的使用场景、工具包及示例总结
2015-08-26 15:47
423 查看
最近处理一个业务需要动态的生成一些业务模型和库,使用到了Emit的处理,相关的资料整理一下供参考。
应用中自定义一个自己的语言
运行中动态的创建类型、模块等,同时又需要提高效率(可以动态编译一次,然后就不用再处理了)
延迟绑定对象的使用,在和Office这类的软件时会用到
动态插件系统等
…
System.Reflection.Emit主要的类:
AssemblyBuilder 应用的初始点,反射发出代码、创建动态Modules
ModuleBuilder 添加类型如类、结构等
ILGenerator.OpCodes 生成 MSIL 指令
使用封装类进行开发:如下的形式
RunSharp:提供了一个类似C#对应语言的包装形式,熟悉后可很快应用,而且编写的代码页比较少
BLToolkit:类似IL的形式进行使用,需要对IL熟悉后才能使用
下文对三种形式一个举例,可以根据实际情况选择
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");
}
}
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();
http://www.bltoolkit.net/Doc.EmitHelloWorld.ashx 这个工具包关于反射发出的使用例子
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");
}
}
}
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 这个工具包关于反射发出的使用例子
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");
}
}
}
相关文章推荐
- SQL——指定表名和列名,删除对应的列
- hdoj 2094 产生冠军
- wsimport命令构建WebService客户端
- 计算机如何表示小数
- POJ -2635-The Embarrassed Cryptographer-数论
- matchTemplate函数
- 创建Tab页并且在存在的情况下刷新页面
- 通过句柄恢复Linux下误删除的数据库数据文件
- PCI Express的几个基本概念
- Spring定时任务的几种用法
- Service
- 64位系统 安装oracle
- Menu学习,和如何实现一步关闭所有的activity退出应用程序
- HttpClient 4.3教程(转载)
- java获取汉字拼音首字母
- iOS链式编程框架介绍之LinkBlock
- 《招聘一个靠谱的iOS》面试题参考答案(下)
- S5PV210内存初始化
- tab标签切换(无炫效果,简单的显示隐藏)
- session丢失返回登陆页