天天看點

代碼生成技術--CodeDom VS T4

     在微軟的自家代碼生成方案中我們有兩種選擇方式:codedom 和text template transformation toolkit(t4)模闆。同樣我們可以利用簡單的string或者stringbuilder來拼接字元串,但是那對于簡單的還可以,但是對于複雜的問題就

代碼生成技術--CodeDom VS T4

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:

代碼生成技術--CodeDom VS T4
代碼生成技術--CodeDom VS T4

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();

        } 

    } 

代碼生成技術--CodeDom VS T4

2:t4 code:

代碼生成技術--CodeDom VS T4
代碼生成技術--CodeDom VS T4

<#@ template language="c#" #>

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 VS T4

 三:總結:

codedom的優勢:

1:具有語言層次抽象,獨立性:是一個單語言開發,多語言生成的方式。

2:framework 的支援:作為我們的.net framework 一部分出現的,位于system.codedom命名空間下。不需要想t4 模闆一樣引用microsoft.visualstudio.texttemplating.dll

t4優勢:

1:更加貼切:采用的是類似于asp、asp.net的語言塊,是的我們的開發更貼切,采用模闆方式更加簡潔,快速。

2:可維護性:由于是基于檔案,不像codedom編譯成為dll方式,我們可以随時修改template檔案、重構。

其實我覺得隻要是不要求語言獨立性,多語言生成的話,就采用t4或者razor等模闆。

代碼生成技術(目前完成,還在繼續,好久沒寫了...):

<a></a>

<a href="http://home.cnblogs.com/u/whitewolf/" target="_blank"></a>