举例在项目中动态构建自己的程序集,.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;
            }
        }
    }
}

posted @ 2008-11-29 01:44  陶勇强  阅读(1216)  评论(3编辑  收藏  举报