DynamicMethod 定义和表示动态方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using System.Reflection;
using System.Reflection.Emit;

namespace UnityDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            //实例化DynamicMethod
            DynamicMethod md = new DynamicMethod("hello", null, new Type[] { typeof(string) }, typeof(Program).Module);

            //生成MSIL生成器,该生成器可用于发出动态方法的方法体
            ILGenerator il = md.GetILGenerator();
      
            //定义要执行的方法
            MethodInfo call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });

            //将指定的指令放到指令流上,将索引为 0 的参数加载到计算堆栈上。
            il.Emit(OpCodes.Ldarg_0);

            //调用由传递的方法说明符指示的方法
            il.Emit(OpCodes.Call, call);

            //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上
            il.Emit(OpCodes.Ret);

            //创建一个可用于执行该方法的委托
            Action<string> writeLineDelegate = (Action<string>)md.CreateDelegate(typeof(Action<string>));

            writeLineDelegate("hello world");
            Console.ReadLine();
        }
    }
}

DynamicMethod类: http://msdn.microsoft.com/zh-cn/library/80h6baz2%28v=vs.80%29.aspx

ILGenerator类:http://msdn.microsoft.com/zh-cn/library/wz52k528.aspx

OpCodes类:http://msdn.microsoft.com/zh-cn/library/x2ebty98%28v=vs.95%29.aspx

如何:定义和执行动态方法:http://msdn.microsoft.com/zh-cn/library/exczf7b9%28v=vs.80%29.aspx

unity生成对象的底层实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using System.Reflection;
using System.Reflection.Emit;

namespace UnityDemo
{
    class Program
    {
        //setExisting的方法原型是Void set_Existing(System.Object)
        private static readonly MethodInfo setExisting =
        typeof(BuilderContext).GetProperty("Existing").GetSetMethod();

        static void Main(string[] args)
        {
            //定义一个动态方法,方法的名字是BuildUpMyMockLogger,该方法有一个BuilderContext参数,返回值为空,创建在UnityDemo.exe模块里
            DynamicMethod buildMethod = new DynamicMethod("BuildUpMyMockLogger",typeof(void),
                new Type[] { typeof(BuilderContext) }, typeof(Program).Module);

            //取得IL
            ILGenerator il = buildMethod.GetILGenerator();

            //获取MyMockLogger构造方法
            ConstructorInfo selectedCtor = typeof(MyMockLogger).GetConstructors()[0];

            //创建一个MyMockLogger新实例,并将对象引用推送到计算堆栈上
            il.Emit(OpCodes.Newobj, selectedCtor);

            //声明MyMockLogger的变量existingObjectLocal
            LocalBuilder existingObjectLocalMyMockLogger = il.DeclareLocal(typeof(MyMockLogger));

            //从计算堆栈的顶部弹出MyMockLogger并将其存储到指定索引处的局部变量列表中existingObjectLocal
            il.Emit(OpCodes.Stloc, existingObjectLocalMyMockLogger);

            //将索引为 0 的参数加载到计算堆栈上 BuilderContext参数
            il.Emit(OpCodes.Ldarg_0);

            //将指定索引处的局部变量加载到计算堆栈上,把existingObjectLocalMyMockLogger传入set_Existing(System.Object)
            il.Emit(OpCodes.Ldloc, existingObjectLocalMyMockLogger);

            //对对象调用后期绑定方法,并且将返回值推送到计算堆栈上
            il.EmitCall(OpCodes.Callvirt, setExisting, null);

            //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上
            il.Emit(OpCodes.Ret);

            //创建一个可用于执行该方法的委托
            DynamicMethodBuildPlan p = new DynamicMethodBuildPlan((DynamicBuildPlanMethod)buildMethod.CreateDelegate(typeof(DynamicBuildPlanMethod)));

            BuilderContext context = new BuilderContext();
            if (context.Existing == null)
            {
                Console.WriteLine("context.Existing == null");
            }
            //调用动态生成的方法
            p.BuildUp(context);

            ((MyMockLogger)context.Existing).SayHello();

            Console.ReadLine();
        }
    }

    class BuilderContext
    {
        private object m = null;
        public object Existing
        {
            get
            {
                return m;
            }
            set
            {
                m = value;
            }
        }
    }

    delegate void DynamicBuildPlanMethod(BuilderContext context);

    class DynamicMethodBuildPlan
    {
        private DynamicBuildPlanMethod planMethod;

        public DynamicMethodBuildPlan(DynamicBuildPlanMethod planMethod)
        {
            this.planMethod = planMethod;
        }

        public void BuildUp(BuilderContext context)
        {
            planMethod(context);
        }
    }

    class MyMockLogger
    {
        public MyMockLogger()
        {
            Console.WriteLine("MyMockLogger() Invoked");
        }

        public void SayHello()
        {
            Console.WriteLine("SayHello() in MyMockLogger");
        }
    }
}
原文地址:https://www.cnblogs.com/50614090/p/2332669.html