天天看點

CodeDom系列-開篇HelloWord

最近在自己實踐一個異常撲捉設計,在子產品中我覺得該給使用者提供的是代碼生成工具,而不是怎麼去做,再自己去寫代碼。現在代碼模闆生成的有很多

但我選擇了用微軟的CODEDOM技術來實作,由于比較熟悉,以及感覺我将隻用在.NET平台是已經夠強大了。最近也總想寫點部落格,但是不知道寫些什麼,是以就準備寫個CODEDOM的系列。僅是開篇,就寫個簡單的HelloWord程式吧。

CODEDOM在.NET Framework SDK文檔裡是這麼講述的: .NET Framework 中包含一個名為“代碼文檔對象模型”(CodeDOM) 的機制,該機制使編寫源代碼的程式的開發人員可以在運作時,根據表示所呈現代碼的單一模型,用多種程式設計語言生成源代碼。 為表示源代碼,CodeDOM 元素互相連結以形成一個資料結構(稱為 CodeDOM 圖),它以某種源代碼的結構為模型。 System.CodeDom 命名空間定義可以表示源代碼的邏輯結構(與具體的程式設計語言無關)的類型。System.CodeDom.Compiler 命名空間定義從 CodeDOM 圖生成源代碼的類型,和在受支援的語言中管理源代碼編譯的類型。編譯器供應商或開發人員可以擴充受支援語言的集合。 還是先貼上代碼:
CodeDom系列-開篇HelloWord
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,如需轉載請自行聯系原作者

繼續閱讀