举例在项目中动态构建自己的程序集,.NET产生动态程序集!
买了园子里面专家写的一本书,你必须知道的.NET把第2部分本质-.NET深入浅出.讲述CIL中间语言的部分详细认真的阅读完后,对.NETCLR的运行以及底层的了解随之加深,并把以前项目中运用到的需要产生动态程序集有熟悉了一遍!写了个简单的例子!只有对CIL有所熟悉之后才能对动态产生程序集这项技术下手,
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;
using System.Threading;
namespace _5_CIL
{
/// <summary>
/// 产生动态程序集
/// 陶勇强
/// </summary>
///要动态构造的程序集的类
///public class HelloWord
/// {
/// private string theMessage;
/// public HelloWord()
/// { }
/// public HelloWord(string s)
/// {
/// theMessage = s;
/// }
/// public string GetMsg()
/// {
/// return theMessage;
/// }
/// public void SayHello()
/// {
/// Console.WriteLine("欢迎来到我的HelloWord类!");
/// }
/// }
/// <summary>
/// 下面的代码动态产生程序集<创建上面的类>
/// </summary>
class Program
{
/// <summary>
/// 动态创建程序集,调用传入一个AppDomain类型
/// </summary>
/// <param name="args"></param>
public static void CreateMyAsm(AppDomain curAppDomain)
{
//创建通用的程序集特征
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "MyAssembly";
assemblyName.Version = new Version("1.0.0.0");
//在当前程序域中创建一个新的程序集
AssemblyBuilder assembly = curAppDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
//本人创造的是一个单文件程序集,模块的名字就是程序集的名字
ModuleBuilder module = assembly.DefineDynamicModule("MyAssembly", "MyAssembly.dll");
//定义一个公共类HelloWord
TypeBuilder helloWorldClass = module.DefineType("MyAssembly.HelloWorld", TypeAttributes.Public);
//定义一个私有字符串类型成员
FieldBuilder msgfield = helloWorldClass.DefineField("theMessage", Type.GetType("System.String"),
FieldAttributes.Private);
//构件一个自定义构造函数
Type[] constructorAers = new Type[1];
constructorAers[0] = typeof(string);
ConstructorBuilder conster = helloWorldClass.DefineConstructor(MethodAttributes.Public,
CallingConventions.Standard, constructorAers);
//产生必要的CIL代码到构造函数
ILGenerator contorIl = conster.GetILGenerator();
contorIl.Emit(OpCodes.Ldarg_0);
Type objectClass = typeof(object);
ConstructorInfo super = objectClass.GetConstructor(new Type[0]);
contorIl.Emit(OpCodes.Call, super);
//加载对象的this指针到栈上
contorIl.Emit(OpCodes.Ldarg_0);
//加载输入参数到栈上
contorIl.Emit(OpCodes.Ldarg_1);
contorIl.Emit(OpCodes.Stfld, msgfield);
contorIl.Emit(OpCodes.Ret);
//创建默认构造函数
helloWorldClass.DefineDefaultConstructor(MethodAttributes.Public);
//创建GetMsg()方法
MethodBuilder getMsgMethod = helloWorldClass.DefineMethod("GetMsg", MethodAttributes.Public, typeof(string), null);
ILGenerator methodIl = getMsgMethod.GetILGenerator();
methodIl.Emit(OpCodes.Ldarg_0);
methodIl.Emit(OpCodes.Ldfld, msgfield);
methodIl.Emit(OpCodes.Ret);
//创建SayHello()方法
MethodBuilder getSayHelloMothod = helloWorldClass.DefineMethod("SayHello", MethodAttributes.Public, null, null);
methodIl = getSayHelloMothod.GetILGenerator();
methodIl.EmitWriteLine("欢迎来到我的HelloWord类!\n");
methodIl.Emit(OpCodes.Ret);
//创建HelloWordClass类
helloWorldClass.CreateType();
//保存创建的程序集
assembly.Save("MyAssembly.dll");
}
static void Main(string[] args)
{
try
{
Console.WriteLine("动态生成程序集程序");
//得到当前域
AppDomain curApp = Thread.GetDomain();
//构造创建动态程序集
CreateMyAsm(curApp);
Console.WriteLine("创建程序集,并加载新的程序集到文件\n");
Assembly ass = Assembly.Load("MyAssembly");
//得到HelloWord类型
Type hello = ass.GetType("MyAssembly.HelloWorld");
//创建HelloWord对象并调用构造函数
Console.Write("->请输入内容: ");
string msg = Console.ReadLine();
object[] cotro = new object[1];
cotro[0] = msg;
object obj = Activator.CreateInstance(hello, cotro);
//调用方法动态创建的程序集里面的HelloWord类里面的SayHello方法
Console.WriteLine("->执行方法SayHello\n");
MethodInfo mt = hello.GetMethod("SayHello");
mt.Invoke(obj, null);
//调用GetMsg()方法
Console.WriteLine("输出内容GetMsg()方法\n");
mt = hello.GetMethod("GetMsg");
Console.WriteLine(mt.Invoke(obj, null));
}
catch (Exception e)
{
throw e;
}
}
}
}