动态生成程序技术
DynamicProxy(无特殊说明的化,都指Castle's DynamicProxy for .net中的DynamicProxy技术)是建立在动态程序集生成技术的基础之上的,也就是说程序在运行时动态生成IL代码并被编译执行。
动态程序集生成技术 也就是说序在运行时动态生成IL代码并被编译执行
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconemittingdynamicassemblies.htm
动态程序集System.Reflection.Emit 命名空间中的一组托管类型,它们允许编译器或工具在运行时发出元数据和 Microsoft 中间语言 (MSIL),或者也可以允许它们在磁盘上生成可移植可执行 (PE) 文件。脚本引擎和编译器是此命名空间的主要用户。在本节中,由 System.Reflection.Emit 命名空间提供的功能称为反射发出。
反射发出提供下列服务:
在运行时定义程序集,然后运行这些程序集并/或将它们保存到磁盘。
在运行时定义新程序集中的模块,然后运行这些模块并/或将它们保存到磁盘。
在运行时定义类型,创建这些类型的实例,并调用这些类型的方法。
为定义的模块定义可由调试器和代码分析器这样的工具使用的符号信息。
如果你想了解更多内容:见System.Reflection.Emit下面
改例子来自msdn,有兴趣大家运行下
下面是一个运行的代码示例: 见文件夹TypeResolve
usingSystem;
usingSystem.Text;
usingSystem.Threading;
usingSystem.Reflection;
usingSystem.Reflection.Emit;
//手动写的类和程序与动态的程序集相同的功能
//---
//classPoint{
//
//privateintx;
//privateinty;
//
//publicPoint(intix,intiy){
//
//this.x=ix;
//this.y=iy;
//
//}
//
//publicintDotProduct(Pointp){
//
//return((this.x*p.x)+(this.y*p.y));
//
//}
//
//publicstaticvoidPointMain(){
//
//Console.Write("Enterthe'x'valueforpoint1:");
//intx1=Convert.ToInt32(Console.ReadLine());
//
//Console.Write("Enterthe'y'valueforpoint1:");
//inty1=Convert.ToInt32(Console.ReadLine());
//
//Console.Write("Enterthe'x'valueforpoint2:");
//intx2=Convert.ToInt32(Console.ReadLine());
//
//Console.Write("Enterthe'y'valueforpoint2:");
//inty2=Convert.ToInt32(Console.ReadLine());
//
//Pointp1=newPoint(x1,y1);
//Pointp2=newPoint(x2,y2);
//
//Console.WriteLine("({0},{1}).({2},{3})={4}.",
//x1,y1,x2,y2,p1.DotProduct(p2));
//
//}
//
//}
//---
classAssemblyBuilderDemo
{
publicstaticTypeBuildDynAssembly()
{
//声明类型
TypepointType=null;
//类型所在应用域
AppDomaincurrentDom=Thread.GetDomain();
//为你动态生成的程序集合输入名称
Console.Write("Pleaseenteranameforyournewassembly:");
StringBuilderasmFileNameBldr=newStringBuilder();
asmFileNameBldr.Append(Console.ReadLine());
asmFileNameBldr.Append(".exe");
stringasmFileName=asmFileNameBldr.ToString();
AssemblyNamemyAsmName=newAssemblyName();
myAsmName.Name="MyDynamicAssembly";
//定义程序集
AssemblyBuildermyAsmBldr=currentDom.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.RunAndSave);
//
//withinittoreflectthetypePointinto.
//定义模块
ModuleBuildermyModuleBldr=myAsmBldr.DefineDynamicModule(asmFileName,
asmFileName);
//定义类名
TypeBuildermyTypeBldr=myModuleBldr.DefineType("Point");
//定义个类属性
FieldBuilderxField=myTypeBldr.DefineField("x",typeof(int),
FieldAttributes.Private);
FieldBuilderyField=myTypeBldr.DefineField("y",typeof(int),
FieldAttributes.Private);
//定义构造函数
TypeobjType=Type.GetType("System.Object");
ConstructorInfoobjCtor=objType.GetConstructor(newType[0]);
//定义参数
Type[]ctorParams=newType[]
{typeof(int),typeof(int)};
ConstructorBuilderpointCtor=myTypeBldr.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
ctorParams);
ILGeneratorctorIL=pointCtor.GetILGenerator();
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call,objCtor);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
ctorIL.Emit(OpCodes.Stfld,xField);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_2);
ctorIL.Emit(OpCodes.Stfld,yField);
ctorIL.Emit(OpCodes.Ret);
//定义DotProduct方法
MethodBuilderpointDPBldr=myTypeBldr.DefineMethod("DotProduct",
MethodAttributes.Public,
typeof(int),
newType[]
{myTypeBldr});
ILGeneratordpIL=pointDPBldr.GetILGenerator();
dpIL.Emit(OpCodes.Ldarg_0);
dpIL.Emit(OpCodes.Ldfld,xField);
dpIL.Emit(OpCodes.Ldarg_1);
dpIL.Emit(OpCodes.Ldfld,xField);
dpIL.Emit(OpCodes.Mul_Ovf_Un);
dpIL.Emit(OpCodes.Ldarg_0);
dpIL.Emit(OpCodes.Ldfld,yField);
dpIL.Emit(OpCodes.Ldarg_1);
dpIL.Emit(OpCodes.Ldfld,yField);
dpIL.Emit(OpCodes.Mul_Ovf_Un);
dpIL.Emit(OpCodes.Add_Ovf_Un);
dpIL.Emit(OpCodes.Ret);
//定义PointMain()方法
Console.WriteLine("DotProductbuilt.");
MethodBuilderpointMainBldr=myTypeBldr.DefineMethod("PointMain",
MethodAttributes.Public|
MethodAttributes.Static,
typeof(void),
null);
pointMainBldr.InitLocals=true;
ILGeneratorpmIL=pointMainBldr.GetILGenerator();
//我们调用四个方法
//MethodInfotokens:
//-voidConsole.WriteLine(string)
//-stringConsole.ReadLine()
//-intConvert.Int32(string)
//-voidConsole.WriteLine(string,object[])
MethodInfowriteMI=typeof(Console).GetMethod(
"Write",
newType[]
{typeof(string)});
MethodInforeadLineMI=typeof(Console).GetMethod(
"ReadLine",
newType[0]);
MethodInfoconvertInt32MI=typeof(Convert).GetMethod(
"ToInt32",
newType[]
{typeof(string)});
Type[]wlParams=newType[]
{typeof(string),typeof(object[])};
MethodInfowriteLineMI=typeof(Console).GetMethod(
"WriteLine",
wlParams);
//Althoughwecouldjustrefertothelocalvariablesby
//index(shortintsforLdloc/Stloc,bytesforLdLoc_S/Stloc_S),
//thistime,we'lluseLocalBuildersforclarityandto
//demonstratetheirusageandsyntax.
//定义四个局部变量
LocalBuilderx1LB=pmIL.DeclareLocal(typeof(int));
LocalBuildery1LB=pmIL.DeclareLocal(typeof(int));
LocalBuilderx2LB=pmIL.DeclareLocal(typeof(int));
LocalBuildery2LB=pmIL.DeclareLocal(typeof(int));
//定义两个动态类型的举办变量
LocalBuilderpoint1LB=pmIL.DeclareLocal(myTypeBldr);
LocalBuilderpoint2LB=pmIL.DeclareLocal(myTypeBldr);
LocalBuildertempObjArrLB=pmIL.DeclareLocal(typeof(object[]));
//完成
//Console.Write("Enterthe'x'valueforpoint1:");
//intx1=Convert.ToInt32(Console.ReadLine());
pmIL.Emit(OpCodes.Ldstr,"Enterthe'x'valueforpoint1:");
pmIL.EmitCall(OpCodes.Call,writeMI,null);
pmIL.EmitCall(OpCodes.Call,readLineMI,null);
pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);
pmIL.Emit(OpCodes.Stloc,x1LB);
//完成
//Console.Write("Enterthe'y'valueforpoint1:");
//inty1=Convert.ToInt32(Console.ReadLine());
pmIL.Emit(OpCodes.Ldstr,"Enterthe'y'valueforpoint1:");
pmIL.EmitCall(OpCodes.Call,writeMI,null);
pmIL.EmitCall(OpCodes.Call,readLineMI,null);
pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);
pmIL.Emit(OpCodes.Stloc,y1LB);
//Console.Write("Enterthe'x'valueforpoint2:");
//intx2=Convert.ToInt32(Console.ReadLine());
pmIL.Emit(OpCodes.Ldstr,"Enterthe'x'valueforpoint2:");
pmIL.EmitCall(OpCodes.Call,writeMI,null);
pmIL.EmitCall(OpCodes.Call,readLineMI,null);
pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);
pmIL.Emit(OpCodes.Stloc,x2LB);
//Console.Write("Enterthe'y'valueforpoint2:");
//inty2=Convert.ToInt32(Console.ReadLine());
pmIL.Emit(OpCodes.Ldstr,"Enterthe'y'valueforpoint2:");
pmIL.EmitCall(OpCodes.Call,writeMI,null);
pmIL.EmitCall(OpCodes.Call,readLineMI,null);
pmIL.EmitCall(OpCodes.Call,convertInt32MI,null);
pmIL.Emit(OpCodes.Stloc,y2LB);
//Pointp1=newPoint(x1,y1);
pmIL.Emit(OpCodes.Ldloc,x1LB);
pmIL.Emit(OpCodes.Ldloc,y1LB);
pmIL.Emit(OpCodes.Newobj,pointCtor);
pmIL.Emit(OpCodes.Stloc,point1LB);
//Pointp2=newPoint(x2,y2);
pmIL.Emit(OpCodes.Ldloc,x2LB);
pmIL.Emit(OpCodes.Ldloc,y2LB);
pmIL.Emit(OpCodes.Newobj,pointCtor);
pmIL.Emit(OpCodes.Stloc,point2LB);
完成计算#region完成计算
//Console.WriteLine("({0},{1}).({2},{3})={4}.",
//x1,y1,x2,y2,p1.DotProduct(p2));
//
pmIL.Emit(OpCodes.Ldstr,"({0},{1}).({2},{3})={4}.");
pmIL.Emit(OpCodes.Ldc_I4_5);
pmIL.Emit(OpCodes.Newarr,typeof(Object));
pmIL.Emit(OpCodes.Stloc,tempObjArrLB);
pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_0);
pmIL.Emit(OpCodes.Ldloc,x1LB);
pmIL.Emit(OpCodes.Box,typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_1);
pmIL.Emit(OpCodes.Ldloc,y1LB);
pmIL.Emit(OpCodes.Box,typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_2);
pmIL.Emit(OpCodes.Ldloc,x2LB);
pmIL.Emit(OpCodes.Box,typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_3);
pmIL.Emit(OpCodes.Ldloc,y2LB);
pmIL.Emit(OpCodes.Box,typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_4);
pmIL.Emit(OpCodes.Ldloc,point1LB);
pmIL.Emit(OpCodes.Ldloc,point2LB);
pmIL.EmitCall(OpCodes.Callvirt,pointDPBldr,null);
pmIL.Emit(OpCodes.Box,typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc,tempObjArrLB);
pmIL.EmitCall(OpCodes.Call,writeLineMI,null);
#endregion
//结束
pmIL.Emit(OpCodes.Ret);
Console.WriteLine("PointMain(entrypoint)built.");
pointType=myTypeBldr.CreateType();
Console.WriteLine("Typebaked.");
myAsmBldr.SetEntryPoint(pointMainBldr);
myAsmBldr.Save(asmFileName);
Console.WriteLine("Assemblysavedas'{0}'.",asmFileName);
Console.WriteLine("Type'{0}'attheprompttorunyournew"+
"dynamicallygenerateddotproductcalculator.",
asmFileName);
//Afterexecution,thisprogramwillhavegeneratedandwrittentodisk,
//inthedirectoryyouexecuteditfrom,aprogramnamed
//<name_you_entered_here>.exe.Youcanrunitbytyping
//thenameyougaveitduringexecution,inthesamedirectorywhere
//youexecutedthisprogram.
returnpointType;
}
publicstaticvoidMain()
{
TypemyType=BuildDynAssembly();
Console.WriteLine("---");
//Let'sinvokethetype'Point'createdinourdynamicassembly.
objectptInstance=Activator.CreateInstance(myType,newobject[]
{0,0});
myType.InvokeMember("PointMain",
BindingFlags.InvokeMethod,
null,
ptInstance,
newobject[0]);
Console.ReadLine();
}
}
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。