最近在自己實踐一個異常撲捉設計,在子產品中我覺得該給使用者提供的是代碼生成工具,而不是怎麼去做,再自己去寫代碼。現在代碼模闆生成的有很多
但我選擇了用微軟的CODEDOM技術來實作,由于比較熟悉,以及感覺我将隻用在.NET平台是已經夠強大了。最近也總想寫點部落格,但是不知道寫些什麼,是以就準備寫個CODEDOM的系列。僅是開篇,就寫個簡單的HelloWord程式吧。
CODEDOM在.NET Framework SDK文檔裡是這麼講述的: .NET Framework 中包含一個名為“代碼文檔對象模型”(CodeDOM) 的機制,該機制使編寫源代碼的程式的開發人員可以在運作時,根據表示所呈現代碼的單一模型,用多種程式設計語言生成源代碼。 為表示源代碼,CodeDOM 元素互相連結以形成一個資料結構(稱為 CodeDOM 圖),它以某種源代碼的結構為模型。 System.CodeDom 命名空間定義可以表示源代碼的邏輯結構(與具體的程式設計語言無關)的類型。System.CodeDom.Compiler 命名空間定義從 CodeDOM 圖生成源代碼的類型,和在受支援的語言中管理源代碼編譯的類型。編譯器供應商或開發人員可以擴充受支援語言的集合。 還是先貼上代碼:using System; using System.Text; using System.CodeDom; using System.CodeDom.Compiler; namespace CodeDomDemo1 { class Program { static void Main(string[] args) { Program pro = new Program(); CodeNamespace nspace = pro.CreateCodeDomHelloDemo(); Console.WriteLine(pro.GengerCode(nspace)); string filename = "HelloWorld.exe"; CompilerResults result= pro.Execute(nspace,filename); if (result.Errors.HasErrors)//是否存在錯誤; { for (int i = 0; i < result.Output.Count; i++) Console.WriteLine(result.Output[i]); for (int i = 0; i < result.Errors.Count; i++) Console.WriteLine(i.ToString() + ": " + result.Errors[i].ToString()); } else System.Diagnostics.Process.Start(filename);//這裡比較懶,不想動手去自己打開,呵呵; Console.Read(); } public CodeNamespace CreateCodeDomHelloDemo() CodeMemberMethod method = new CodeMemberMethod();//方法聲明; method.Name = "SayHello";// 方法名 method.Attributes = MemberAttributes.Public| MemberAttributes.Final;//屬性 method.ReturnType = new CodeTypeReference(typeof(string));//傳回類型 method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression("Hello from code!")));//方法體,隻有一句傳回語句return "Hello from code!"; CodeEntryPointMethod main = new CodeEntryPointMethod();//主方法Main main.Statements.Add(new CodeVariableDeclarationStatement("HelloWord","hw", new CodeObjectCreateExpression("HelloWord", new CodeExpression[] { })));//變量聲明:HelloWord hw = new HelloWord(); CodeMethodInvokeExpression methodinvoke= new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("hw"),"SayHello",new CodeExpression[]{}); main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine", methodinvoke)); main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read"));//兩個方法調用:System.Console.WriteLine(hw.SayHello()); CodeTypeDeclaration helloword = new CodeTypeDeclaration("HelloWord");//類型Class聲明 helloword.Attributes = MemberAttributes.Public; helloword.Members.AddRange(new CodeTypeMember[]{method,main});//添加方法到clss CodeNamespace nspace = new CodeNamespace("HelloDemo1");//命名空間聲明 nspace.Imports.Add(new CodeNamespaceImport("System"));//引入程式命名空間:using System; nspace.Types.Add(helloword);// return nspace; public string GengerCode(CodeNamespace nspace) StringBuilder sb = new StringBuilder(); System.IO.StringWriter sw = new System.IO.StringWriter(sb); CodeGeneratorOptions geneOptions = new CodeGeneratorOptions();//代碼生成選項 geneOptions.BlankLinesBetweenMembers = false; geneOptions.BracingStyle = "C"; geneOptions.ElseOnClosing = true; geneOptions.IndentString = " "; CodeDomProvider.GetCompilerInfo("c#").CreateProvider().GenerateCodeFromNamespace(nspace, sw, geneOptions);//代碼生成 sw.Close(); return sb.ToString(); public CompilerResults Execute(CodeNamespace nspace, string filename) CodeCompileUnit unit=new CodeCompileUnit();//code編譯單元 unit.Namespaces.Add(nspace); CodeDomProvider provider= CodeDomProvider.CreateProvider("C#"); CompilerParameters options=new CompilerParameters();// options.GenerateInMemory =false;//是否在記憶體中生成; options.IncludeDebugInformation =true;// 包含調試資訊; options.ReferencedAssemblies.Add("System.dll"); options.OutputAssembly = filename; if (System.IO.Path.GetExtension(filename).ToLower() == ".exe") options.GenerateExecutable = true;//true為可執行exe,false:dll options.GenerateExecutable = false;//true為可執行exe,false:dll return provider.CompileAssemblyFromDom(options, unit);//編譯程式集 } }![]()
CodeDom系列-開篇HelloWord ![]()
CodeDom系列-開篇HelloWord
2:運作結果:![]()
CodeDom系列-開篇HelloWord
上面代碼很簡單,我特意也把注釋寫上了,是以不用一句一句的講解了,哈哈。 CodeDom提供了很多操作,如定義類,還可以定義結構、枚舉;類裡面的方法、屬性、字段及構造函數;定義Attribute;事件及委托;指派、條件(if)、循環(for)語句;變量聲明;異常處理語句;甚至還可以加注釋以及塊(#region #endregion)。除了分支選擇switch、while,dowhile循環及break、continue沒發現外,其他大多數東西都有,着已經足夠了,程式三大結構,足以實作很多的代碼生成了。
本文轉自破狼部落格園部落格,原文連結:http://www.cnblogs.com/whitewolf/archive/2010/06/19/1760708.html,如需轉載請自行聯系原作者