Reflection.Emit的使用场景、工具包及示例总结
?最近處理一個(gè)業(yè)務(wù)需要?jiǎng)討B(tài)的生成一些業(yè)務(wù)模型和庫(kù),使用到了Emit的處理,相關(guān)的資料整理一下供參考。
Reflection.Emit目的
使用的場(chǎng)景:
- 應(yīng)用中自定義一個(gè)自己的語言
- 運(yùn)行中動(dòng)態(tài)的創(chuàng)建類型、模塊等,同時(shí)又需要提高效率(可以動(dòng)態(tài)編譯一次,然后就不用再處理了)
- 延遲綁定對(duì)象的使用,在和Office這類的軟件時(shí)會(huì)用到
- 動(dòng)態(tài)插件系統(tǒng)等
- …
System.Reflection.Emit主要的類:
- AssemblyBuilder 應(yīng)用的初始點(diǎn),反射發(fā)出代碼、創(chuàng)建動(dòng)態(tài)Modules
- ModuleBuilder 添加類型如類、結(jié)構(gòu)等
- ILGenerator.OpCodes 生成 MSIL 指令
反射發(fā)出開發(fā)時(shí)可用的工具包
直接使用框架基礎(chǔ)類開發(fā):比較繁瑣,對(duì)于比較簡(jiǎn)單的,可以使用http://reflectoraddins.codeplex.com/wikipage?title=ReflectionEmitLanguage&referringTitle=Home 這個(gè)Reflector插件,查看類、方法和組件對(duì)應(yīng)的代碼,可以處理一些比較簡(jiǎn)單的應(yīng)用
使用封裝類進(jìn)行開發(fā):如下的形式
????? RunSharp:提供了一個(gè)類似C#對(duì)應(yīng)語言的包裝形式,熟悉后可很快應(yīng)用,而且編寫的代碼頁比較少
????? BLToolkit:類似IL的形式進(jìn)行使用,需要對(duì)IL熟悉后才能使用
?
下文對(duì)三種形式一個(gè)舉例,可以根據(jù)實(shí)際情況選擇
?
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 ?簡(jiǎn)要的說明
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 ?這個(gè)工具包關(guān)于反射發(fā)出的使用例子
?
代碼 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");
}
}
}
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/2018/archive/2011/01/17/1937564.html
總結(jié)
以上是生活随笔為你收集整理的Reflection.Emit的使用场景、工具包及示例总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arcgis server 常见问题【转
- 下一篇: JQuery Highcharts图表控