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"); } } }