ASP.NET----动态发射程序集

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection.Emit;
using System.Threading;
using System.Reflection;

namespace NET.MST.Sixth.EmitAssembly
{
class MainClass
{
/// <summary>
/// 使用发射的类型
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
//定义构造方法的参数
Object[] ctorParams = new Object[2];
ctorParams[
0] = 1000;
ctorParams[
1] = 2000;
//发射程序集,并得到AddClass类型
Type type = CreateAssembly();
//新建AddClass对象
object ptInstance = Activator.CreateInstance(type, ctorParams);
//调用动态发射的ToString方法
Console.WriteLine(ptInstance.ToString());
//调用动态发射的GetResult方法
MethodInfo info = type.GetMethod("GetResult",new Type[0]);
long result = (long)info.Invoke(ptInstance, null);
Console.WriteLine(result.ToString());
Console.Read();
}

/// <summary>
/// 用来动态发射一个程序集的中间代码
/// 放回发射的类型
/// 创建的中间代码相当于这样的C#代码:
// public class AddClass
//{
// private long first;
// private long second;

// public AddClass(long f, long s)
// {
// first = f;
// second = s;
// }
// public long GetResult()
// {
// return first + second;
// }

// public override string ToString()
// {
// return "第一个数字是:" +
// first.ToString() +
// "\r\n第二个数字是:" +
// second.ToString();
// }
// }
/// </summary>
static Type CreateAssembly()
{
//在当前应用程序域中定义新程序集
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName
= new AssemblyName();
myAsmName.Name
= "NewAssembly";
AssemblyBuilder assemblybuilder
= myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave);
//定义模块
ModuleBuilder addclassModule = assemblybuilder.DefineDynamicModule("AddClass", "AddClass.dll");
//定义模块中的类型
TypeBuilder addclass = addclassModule.DefineType("AddClass", TypeAttributes.Public);
//这个类型将包含两个私有成员
//名字分别为:first和second
FieldBuilder first = addclass.DefineField("first", typeof(long), FieldAttributes.Private);
FieldBuilder second
= addclass.DefineField("second", typeof(long), FieldAttributes.Private);
//为AddClass定义一个公共构造方法
//接受两个长整型参数
Type[] ctorParams = new Type[] { typeof(long), typeof(long) };
//AddClass的基类是System.Object
Type objType = Type.GetType("System.Object");
//得到无参数构造方法
ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);
//AddClass的公共构造方法
ConstructorBuilder addCtor = addclass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctorParams);
//开始生成构造方法的中间代码
ILGenerator ctorIL = addCtor.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, first);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_2);
ctorIL.Emit(OpCodes.Stfld, second);
ctorIL.Emit(OpCodes.Ret);
//这里生成long GetResult()方法
//用以得到两个数字相加的结果
MethodBuilder resultMethod = addclass.DefineMethod("GetResult", MethodAttributes.Public, typeof(long), new Type[0]);
//发射GetResult方法的中间代码
ILGenerator resultIL = resultMethod.GetILGenerator();
// ILGenerator.EmitWriteLine(string) 生成一个字符串对象,
//并且通过控制台输出
resultIL.EmitWriteLine("开始执行相加:");
//执行相加程序
//这里的IL代码用来导入两个成员变量,相加并返回结果
resultIL.Emit(OpCodes.Ldarg_0);
resultIL.Emit(OpCodes.Ldfld, first);
resultIL.Emit(OpCodes.Ldarg_0);
resultIL.Emit(OpCodes.Ldfld, second);
resultIL.Emit(OpCodes.Add);
resultIL.Emit(OpCodes.Ret);
//发射String ToString方法
MethodBuilder tostringMethod = addclass.DefineMethod("ToString", MethodAttributes.Virtual | MethodAttributes.Public, typeof(String), new Type[0]);
ILGenerator stringIL
= tostringMethod.GetILGenerator();
stringIL.Emit(OpCodes.Ldstr,
"第一个数字是:");
stringIL.Emit(OpCodes.Ldarg_0);
stringIL.Emit(OpCodes.Ldflda, first);
stringIL.Emit(OpCodes.Call,
typeof(long).GetMethod("ToString",new Type[0]));
stringIL.Emit(OpCodes.Ldstr,
"\r\n第二个数字是:");
stringIL.Emit(OpCodes.Ldarg_0);
stringIL.Emit(OpCodes.Ldflda, second);
stringIL.Emit(OpCodes.Call,
typeof(long).GetMethod("ToString", new Type[0]));
Type[] types
= new Type[4];
for (int i = 0; i < types.Length; i++)
types[i]
= typeof(String);
stringIL.Emit(OpCodes.Call,
typeof(String).GetMethod("Concat",types));
stringIL.Emit(OpCodes.Ret);
//说明方法重载System.Object方法
addclass.DefineMethodOverride(tostringMethod, typeof(System.Object).GetMethod("ToString"));
return addclass.CreateType();
}
}
}
posted @ 2011-06-11 22:31  brainmao  阅读(356)  评论(0编辑  收藏  举报