C# 使用CodeDomProvider编译.cs文件 [岳阳原创]
从这里例子中可以了解:
1. 如何Compile .cs文件
2. 如何用Reflection遍历属性
需求:
最近改写了RepositoryFactory for SQLite, 改完后开始想为什么不自己也做个自动生成?
这样只要写好了类,根据类名字,类的属性字段可以自动生成对类名(表名)的增删改查。
做之前,需要研究两个内容。
1. 要能从类中得到属性列表。
2. T4,怎么把属性列表传进去。
这里主要解决问题1.
我们目前有一个类,对应数据库中的表名。
using System; using System.Collections.Generic; using System.Text; namespace Cano.DataLoader.Models { public class TableModel { private int _id; public int Id { set { _id = value; } get { return _id; } } private int _size; public int Size { set { _size = value; } get { return _size;} } } }
然后要用到CodeDomProvider 中的CompileAssemblyFromFile 方法,这个方法主需要设定好CompilerParameters,还有源文件就可以了,比用Dom简单许多。
代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Net; using System.IO; using System.Reflection; using System.CodeDom; using System.CodeDom.Compiler; using System.Xml.Serialization; namespace WpfApplicationTestCompile { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); TestCompile(); } public void TestCompile() { string @namespace = "Cano.DataLoader.Models"; // 设定编译参数,DLL代表需要引入的Assemblies CompilerParameters cplist = new CompilerParameters(); cplist.GenerateExecutable = false; cplist.GenerateInMemory = true; cplist.ReferencedAssemblies.Add("System.dll"); cplist.ReferencedAssemblies.Add("System.XML.dll"); cplist.ReferencedAssemblies.Add("System.Data.dll"); // 编译代理类,C# CSharp都可以 CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp"); // 文件数组,我只需要一个file string[] sources = new string[1]; sources[0]=@"d:\TableModel.cs"; CompilerResults cr = provider1.CompileAssemblyFromFile(cplist, sources); if (true == cr.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) { sb.Append(ce.ToString()); sb.Append(System.Environment.NewLine); } throw new Exception(sb.ToString()); } // 获得类的Type, 如果要生成实例,需要调用assembly.CreateInstance System.Reflection.Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType(@namespace + "." + "TableModel", true, true); // 获得属性列表,顺表排个序 IOrderedEnumerable<System.Reflection.PropertyInfo> pi = t.GetProperties().OrderBy(item => item.Name); foreach (PropertyInfo propertyInfo in pi) { string propertyName = propertyInfo.Name; string propertyType = propertyInfo.PropertyType.Name; } } } }