实现一个C#动态编译系统[实体类代码生成器代码分析]

在"实体类代码生成器3"中,用户可以使用C#代码来动态生成一些参数,比如代码类名生成规则,表名生成规则,初始化规则等.而要调用这些代码显然需要对代码进行运行时动态编译,幸好C#有了"万能"的反射系统,可以让我们轻松动态编译代码并调用.

OK,现在详细了解下"实体类代码生成器"中的动态编译类,首先定义一个RunnerMethod对象,用来保存和方法有关的信息:

C#代码
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Text;   
  4. using System.Reflection;   
  5. using CodeFactory.Library.Language;   
  6. using CodeFactory.Library.Config;   
  7.   
  8. namespace CodeFactory.Library.CodeRunner   
  9. {   
  10.     public class RunnerMethod   
  11.     {   
  12.         private MethodInfo method;   
  13.         private object runnerObject;   
  14.   
  15.         public RunnerMethod()   
  16.         {   
  17.         }   
  18.   
  19.         public MethodInfo Method   
  20.         {   
  21.             get { return this.method; }   
  22.             set { this.method = value; }   
  23.         }   
  24.   
  25.         public object RunnerObject   
  26.         {   
  27.             get { return this.runnerObject; }   
  28.             set { this.runnerObject = value; }   
  29.         }   
  30.   
  31.         public object Run(object[] paras)   
  32.         {   
  33.             return this.method.Invoke(this.runnerObject, paras);   
  34.         }   
  35.     }   
  36. }   

 

然后实现Runner类:

 

C#代码
  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Text;   
  4. using System.CodeDom;   
  5. using System.CodeDom.Compiler;   
  6. using System.Reflection;   
  7. using System.IO;   
  8. using CodeFactory.Library.Language;   
  9. using CodeFactory.Library.Config;   
  10.   
  11. namespace CodeFactory.Library.CodeRunner   
  12. {   
  13.     public class Runner   
  14.     {   
  15.         private EncoderInfo coderInfo;   
  16.         private string codeText;   
  17.   
  18.         public EncoderInfo CodeInfo   
  19.         {   
  20.             get { return this.coderInfo; }   
  21.             set { this.coderInfo = value; }   
  22.         }   
  23.   
  24.         public string CodeText   
  25.         {   
  26.             get { return this.codeText; }   
  27.         }   
  28.   
  29.         public Runner()   
  30.         {   
  31.             this.coderInfo = ConfigManager.Info.SysEncoder;   
  32.             this.codeText = string.Empty;   
  33.         }   
  34.   
  35.         public Runner(EncoderInfo rcode)   
  36.         {   
  37.             this.coderInfo = rcode;   
  38.             this.codeText = string.Empty;   
  39.         }   
  40.   
  41.         public object Run(string methodName, object[] paras)   
  42.         {   
  43.             RunnerMethod method = this.CreateMethod(methodName);   
  44.             return method.Run(paras);   
  45.         }   
  46.   
  47.         public RunnerMethod CreateMethod(string methodName)   
  48.         {   
  49.             StreamReader sr = new StreamReader(ConfigManager.CurrentPath + "\\" + this.coderInfo.CodeFile);  
  50.             this.codeText = sr.ReadToEnd();  
  51.             sr.Close();  
  52.             CompilerParameters vCompilerParameters = new CompilerParameters();  
  53.             vCompilerParameters.GenerateExecutable = false;  
  54.             vCompilerParameters.GenerateInMemory = true;  
  55.             foreach (string s in this.coderInfo.AssemblieList)  
  56.             {  
  57.                 vCompilerParameters.ReferencedAssemblies.Add(s);  
  58.             }  
  59.             CompilerResults vCompilerResults =  
  60.                 CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(vCompilerParameters, this.codeText);  
  61.             Assembly vAssembly = null;  
  62.             try  
  63.             {  
  64.                 vAssembly = vCompilerResults.CompiledAssembly;  
  65.             }  
  66.             catch (Exception)  
  67.             {  
  68.                 throw new Exception(LanguageManager.StringManager["Error_RunCode"]);   
  69.             }   
  70.             object vTemp = vAssembly.CreateInstance(this.coderInfo.ClassName);   
  71.             Type t = vTemp.GetType();   
  72.             MethodInfo method = vTemp.GetType().GetMethod(methodName);   
  73.             RunnerMethod m = new RunnerMethod();   
  74.             m.RunnerObject = vTemp;   
  75.             m.Method = method;   
  76.             return m;   
  77.         }   
  78.     }   
  79. }   

 

该类关键是CreateMethod方法,它用来生成编译后的方法对象供程序调用.当然,代码还有一些优化的空间,不过对于本程序,已经完全足矣.

posted @ 2009-05-22 15:21  起源  阅读(809)  评论(1编辑  收藏  举报