zoukankan      html  css  js  c++  java
  • Reflection.Emit的使用场景、工具包及示例总结

     最近处理一个业务需要动态的生成一些业务模型和库,使用到了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  这个工具包关于反射发出的使用例子

     

    代码
    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");

    }

    }

    }

     

     

  • 相关阅读:
    高德地图周边搜索与搜索提示(三)
    jupyter notebook 添加目录
    Ubuntu 下简单完全卸载MySQL 以及便捷安装
    Ubuntu中安装MySQL,更改默认用户密码
    python-pip版本更新
    概率论与数理统计--->陈希孺---书籍链接下载
    机器学习实战-书籍链接下载
    Markdown安装/破解/下载
    Kaggle比赛入门比赛--Titanic-测试玩--
    python机器学习算法简介
  • 原文地址:https://www.cnblogs.com/2018/p/1937564.html
Copyright © 2011-2022 走看看