using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
//动态创建程序集 by 1987Raymond 2008.7.17
//使用动态创建程序集的几种情形:
//在web浏览器中执行脚本
//在asp.net页中执行脚本
//使用反射发出编译正则表达式
//利用.net框架利用System.Reflection.Emit命名空间中的一组托管类型,我们可以动态创建程序集,在程序集中直接写入MSIL代码.首先我们可以在当前应用域下创建程序集框架,然后我们可以在该程序集框架下定义模块,接下来在模块对象中定义类型,为类型添加成员属性,在方法中可以直接写入MSIL代码
namespace Demo
{
public interface ISayHello
{
int SayHello();
}
/// <summary>
///ReflectionOfDefineDynamicAssembly 的摘要说明
/// </summary>
public class ReflectionOfDefineDynamicAssembly
{
private ISayHello sayHello = null;
public ReflectionOfDefineDynamicAssembly()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
private Assembly EmitAssembly(string sMsg)
{
//创建程序集名称
AssemblyName assemblyName = new AssemblyName("SayHelloAssembly");
//创建新的动态程序集
AssemblyBuilder newAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
//利用AssemblyBuilder创建ModuleBuilder
ModuleBuilder newModule = newAssembly.DefineDynamicModule("SayHello");
//创建一个公共类MySayHello
TypeBuilder myType = newModule.DefineType("MySayHello", TypeAttributes.Public | TypeAttributes.Class);
//使得该类实现ISayHello接口
myType.AddInterfaceImplementation(typeof(ISayHello));
//方法的传入参数
Type[] paramTypes = new Type[0];//不传入参数
//方法返回的类型
Type returnType = typeof(int);
//定义接口中的方法
MethodBuilder myMethod = myType.DefineMethod("SayHello", MethodAttributes.Public | MethodAttributes.Virtual, returnType, paramTypes);
//获取ILGenerator
ILGenerator generator = myMethod.GetILGenerator();
//编写代码
generator.EmitWriteLine("Hello " + sMsg);
//入栈
generator.Emit(OpCodes.Ldc_I4, 1);
//返回栈顶元素
generator.Emit(OpCodes.Ret);
//获得接口的方法信息
MethodInfo info = typeof(ISayHello).GetMethod("SayHello");
//规定方法重载
myType.DefineMethodOverride(myMethod, info);
//创建类型
myType.CreateType();
return newAssembly;
}
//动态创建程序集
//初始化接口变量
public void GenerateCode(string sMsg)
{
Assembly theAssembly = EmitAssembly(sMsg);
sayHello = (ISayHello)theAssembly.CreateInstance("MySayHello");
}
//设置接口变量 如果不为空则
public int DoSayHello(string sMsg)
{
if (sayHello != null)
{
GenerateCode(sMsg);
}
return sayHello.SayHello();
}
}
public class Test
{
public static void Main()
{
ReflectionOfDefineDynamicAssembly test = new ReflectionOfDefineDynamicAssembly();
int i = test.DoSayHello("1987Raymond/果汁分你一半");
Console.WriteLine(i);
}
}
}