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