天天看点

代码生成技术--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>