代码生成技术--CodeDom VS T4
? ? ?在微軟的自家代碼生成方案中我們有兩種選擇方式:CodeDom 和Text Template Transformation Toolkit(T4)模板。同樣我們可以利用簡單的String或者StringBuilder來拼接字符串,但是那對于簡單的還可以,但是對于復雜的問題就。其實在ASP.NET MVC 3.0中有多處了一個更簡潔語法的模板-Razor,我們同樣可以運用于我們自己的代碼生成中,我隨便有一篇簡單的介紹Razor Templating Engine,在以后有機會了會寫Razor Demo。今天的主題不在這里,所以不多說了。
一:簡介:
CodeDom:這 個類庫出現在我們的.NET Framework 2.0,并且被深深的用于我們的ASP.NET項目中。CodeDom關注于一個語言獨立性,以至于我們可以利用我們熟悉的語言(c#,vb等)構建一個CodeDom Model Tree,就可以生成我們在.NET平臺所支持的語言代碼。對于我們的ASP.NET要求語言的獨立。
T4:T4模板作為VS2008的一部分出現,他以<# #> 、<#= #>接近于ASP.NET的語言在模板中插入一段段的動態代碼塊,可以像asp或者ASP.NET一樣簡單的更讓人貼切,相對于CodeDom就更簡潔,但是沒有了語言層次的抽象,不具有語言獨立性,我們必須為同一個功能的模板在不同的語言上寫不同的模板,但是在開發中往往c#模板就足夠了,以及更簡單化所以得到了更多人的青睞。
二:Code Demo:
下面我們將用CodeDom和t4分別生成一個簡單的Code,根據時間輸出不同的問候,如下:
1:CodeDom Code:
using?System;?using?System.Text;?
using?System.CodeDom;?
using?System.IO;
namespace?RazorDemo?
{?
????public?class?CodedomDemo?
????{?
????????public?CodeCompileUnit?CrateCodeCompileUnit()?
????????{?
????????????var?testClass?=?new?CodeTypeDeclaration("Test");?
????????????var?testMeth?=?new?CodeMemberMethod()?
????????????{?
????????????????Attributes?=?MemberAttributes.Public|?MemberAttributes.Final,?
????????????????Name?=?"SayHello",?
????????????};?
????????????var?param?=?new?CodeParameterDeclarationExpression(new?CodeTypeReference(typeof(string)),?"name");?
????????????testMeth.Parameters.Add(param);?
????????????testClass.Members.Add(testMeth);
????????????var?nowExpression?=?new?CodePropertyReferenceExpression(new?CodePropertyReferenceExpression(new?CodeTypeReferenceExpression(typeof(DateTime)),?"Now"),?"Hour");?
????????????var?assmon?=?new?CodeBinaryOperatorExpression(new?CodePrimitiveExpression("早上好:"),?CodeBinaryOperatorType.Add,?new?CodeArgumentReferenceExpression("name")?);?
????????????var?asslunch?=?new?CodeBinaryOperatorExpression(new?CodePrimitiveExpression("中午好:"),?CodeBinaryOperatorType.Add,?new?CodeArgumentReferenceExpression("name"));?
????????????var?assAfternoon?=?new?CodeBinaryOperatorExpression(new?CodePrimitiveExpression("下午好:"),?CodeBinaryOperatorType.Add,?new?CodeArgumentReferenceExpression("name"));?
????????????var?codecondition?=?new?CodeConditionStatement(new?CodeBinaryOperatorExpression(?
????????????????nowExpression,?CodeBinaryOperatorType.LessThanOrEqual,?new?CodePrimitiveExpression(10)),?
????????????????new?CodeStatement[]?{?new?CodeExpressionStatement(new?CodeMethodInvokeExpression(new?CodeTypeReferenceExpression(typeof(Console)),?"WriteLine",?assmon))?},???????????//true:if(DateTime.Now<=10)?
????????????????//else?
????????????????new?CodeStatement[]?
????????????????{?
???????????????????new?CodeConditionStatement(new?CodeBinaryOperatorExpression(nowExpression,?CodeBinaryOperatorType.LessThanOrEqual,new?CodePrimitiveExpression(14)?),??//?else?if(DateTime.Now<=14)?
?????????????????????new?CodeStatement[]?{?new?CodeExpressionStatement(new?CodeMethodInvokeExpression(new?CodeTypeReferenceExpression(typeof(Console)),?"WriteLine",asslunch))},????//true?
?????????????????????new?CodeStatement[]?{?new?CodeExpressionStatement(new?CodeMethodInvokeExpression(new?CodeTypeReferenceExpression(typeof(Console)),?"WriteLine",assAfternoon))})?//fasle?
????????????????}?
???????????????);
????????????testMeth.Statements.AddRange(new?CodeStatement[]?{?????????????
????????????codecondition?
????????????});
????????????var?ns?=?new?CodeNamespace("Wolf");?
????????????ns.Imports.Add(new?CodeNamespaceImport("System"));?
????????????ns.Types.Add(testClass);?
????????????var?util?=?new?CodeCompileUnit();?
????????????util.Namespaces.Add(ns);?
????????????return?util;?
????????}
????????public?string?Genertor(string?language)?
????????{?
????????????StringBuilder?sb?=?new?StringBuilder();?
????????????StringWriter?sw?=?new?StringWriter(sb);?
????????????System.CodeDom.Compiler.CodeDomProvider.CreateProvider(language).GenerateCodeFromCompileUnit(?
????????????????this.CrateCodeCompileUnit(),?sw,?new?System.CodeDom.Compiler.CodeGeneratorOptions()?
????????????????{?
????????????????????ElseOnClosing?=?true,?
????????????????????IndentString?=?"????"?
????????????????});?
????????????sw.Close();?
????????????return?sb.ToString();
????????}?
????}?
}?
2:T4 Code:
<#@?template?language="C#"?#>using?System;?
namespace?WolfT4?{???
????public?class?Test?{
????????public?void?SayHello(string?name)?{?
????????????<#?if(System.DateTime.Now.Hour<=10){#>?
????????????System.Console.WriteLine(("早上好:"?+?name));?
????????????<#}?else?if(System.DateTime.Now.Hour<=14){#>?
????????????System.Console.WriteLine(("中午好:"?+?name));?
????????????<#}?else{?#>?
????????????System.Console.WriteLine(("下午好:"?+?name));?
????????????<#}#>????????????
????????}?
????}?
}
?三:總結:
CodeDom的優勢:
1:具有語言層次抽象,獨立性:是一個單語言開發,多語言生成的方式。
2:Framework?的支持:作為我們的.NET Framework 一部分出現的,位于System.CodeDom命名空間下。不需要想T4 模板一樣引用Microsoft.VisualStudio.TextTemplating.dll
T4優勢:
1:更加貼切:采用的是類似于ASP、ASP.NET的語言塊,是的我們的開發更貼切,采用模板方式更加簡潔,快速。
2:可維護性:由于是基于文件,不像codedom編譯成為dll方式,我們可以隨時修改Template文件、重構。
?
其實我覺得只要是不要求語言獨立性,多語言生成的話,就采用T4或者Razor等模板。
代碼生成技術(目前完成,還在繼續,好久沒寫了...):
1:CodeDom系列目錄
2:CodeSmith模板引擎系列-目錄
3:Razor Templating Engine
?
?
作者:破??狼?
出處:http://www.cnblogs.com/whitewolf/?
本文版權歸作者,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。該文章也同時發布在我的獨立博客中-個人獨立博客、博客園--破狼和51CTO--破狼。http://www.cnblogs.com/whitewolf/archive/2010/12/23/1914700.html
總結
以上是生活随笔為你收集整理的代码生成技术--CodeDom VS T4的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 源代码自动编译packa
- 下一篇: MongoDB系列(一):简介及安装