实现一个C#动态编译系统[实体类代码生成器代码分析]
在"实体类代码生成器3"中,用户可以使用C#代码来动态生成一些参数,比如代码类名生成规则,表名生成规则,初始化规则等.而要调用这些代码显然需要对代码进行运行时动态编译,幸好C#有了"万能"的反射系统,可以让我们轻松动态编译代码并调用.
OK,现在详细了解下"实体类代码生成器"中的动态编译类,首先定义一个RunnerMethod对象,用来保存和方法有关的信息:
C#代码
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Reflection;
- using CodeFactory.Library.Language;
- using CodeFactory.Library.Config;
- namespace CodeFactory.Library.CodeRunner
- {
- public class RunnerMethod
- {
- private MethodInfo method;
- private object runnerObject;
- public RunnerMethod()
- {
- }
- public MethodInfo Method
- {
- get { return this.method; }
- set { this.method = value; }
- }
- public object RunnerObject
- {
- get { return this.runnerObject; }
- set { this.runnerObject = value; }
- }
- public object Run(object[] paras)
- {
- return this.method.Invoke(this.runnerObject, paras);
- }
- }
- }
然后实现Runner类:
C#代码
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.CodeDom;
- using System.CodeDom.Compiler;
- using System.Reflection;
- using System.IO;
- using CodeFactory.Library.Language;
- using CodeFactory.Library.Config;
- namespace CodeFactory.Library.CodeRunner
- {
- public class Runner
- {
- private EncoderInfo coderInfo;
- private string codeText;
- public EncoderInfo CodeInfo
- {
- get { return this.coderInfo; }
- set { this.coderInfo = value; }
- }
- public string CodeText
- {
- get { return this.codeText; }
- }
- public Runner()
- {
- this.coderInfo = ConfigManager.Info.SysEncoder;
- this.codeText = string.Empty;
- }
- public Runner(EncoderInfo rcode)
- {
- this.coderInfo = rcode;
- this.codeText = string.Empty;
- }
- public object Run(string methodName, object[] paras)
- {
- RunnerMethod method = this.CreateMethod(methodName);
- return method.Run(paras);
- }
- public RunnerMethod CreateMethod(string methodName)
- {
- StreamReader sr = new StreamReader(ConfigManager.CurrentPath + "\\" + this.coderInfo.CodeFile);
- this.codeText = sr.ReadToEnd();
- sr.Close();
- CompilerParameters vCompilerParameters = new CompilerParameters();
- vCompilerParameters.GenerateExecutable = false;
- vCompilerParameters.GenerateInMemory = true;
- foreach (string s in this.coderInfo.AssemblieList)
- {
- vCompilerParameters.ReferencedAssemblies.Add(s);
- }
- CompilerResults vCompilerResults =
- CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(vCompilerParameters, this.codeText);
- Assembly vAssembly = null;
- try
- {
- vAssembly = vCompilerResults.CompiledAssembly;
- }
- catch (Exception)
- {
- throw new Exception(LanguageManager.StringManager["Error_RunCode"]);
- }
- object vTemp = vAssembly.CreateInstance(this.coderInfo.ClassName);
- Type t = vTemp.GetType();
- MethodInfo method = vTemp.GetType().GetMethod(methodName);
- RunnerMethod m = new RunnerMethod();
- m.RunnerObject = vTemp;
- m.Method = method;
- return m;
- }
- }
- }
该类关键是CreateMethod方法,它用来生成编译后的方法对象供程序调用.当然,代码还有一些优化的空间,不过对于本程序,已经完全足矣.