理解模板引擎Razor 的原理

Razor是ASP.NET MVC 3中新加入的技術,以做爲ASPX引擎的一個新的替代項。簡潔的語法與.NET Framework 結合,普遍應用於ASP.NET MVC 項目。Razor Pad是一個編輯Razor腳本的工具,脫離於ASP.NET 和Visual Studio。css

image

微軟已經有一套模板引擎T4,在設計ASP.NET MVC 3時又設計一套模板引擎Razor,對開發者而言是多一種選擇,但同時也增長學習成本,至今我都沒有時間和精力將Code Smith的模板轉化爲T4的模板。html

 

Razor  從模板到.NET 代碼

image

以cshtml爲後綴名的爲Razor模板,能夠混合腳本語言和Html代碼,以呈現爲ASP.NET Page頁面。ide

來看下面的Razor腳本片斷,它以div的格式輸出Posts對象的標題:工具

<div>
@foreach(var post in Posts) {
<div>@post.Title</div>
}
</div>

Razor引擎分析上面的腳本,產生以下所示的Xml文本片斷post

<Document>
  <Markup><div>\r\n\t</Markup>
     <Statement>
      <Transition>@</Transition>
       <Code>foreach(var post in posts) { </Code>
        <Markup>
        <Markup><div></Markup>
       <Expression>
         <Transition>@</Transition>
         <ImplicitExpression>post.Title</ImplicitExpression>
        </Expression>
        <Markup></div></Markup>
        </Markup>
       <Code> } </Code>
      <Markup></div></Markup>
    </Statement>
  <Markup>\r\n</div></Markup>
</Document>

以空格或是@做爲區域(block)的分割符,將Razor解析成一個表達式樹。@在Razor模板中的用法至關靈活,能夠用於表達式的求值,或是定義代碼塊。學習

而後產生.NET代碼,上面的腳本,會產生以下的.NET代碼類型spa

namespace Razor {
public class __CompiledTemplate {
public __CompiledTemplate() {
}
public override void Execute() {
        WriteLiteral("<div>\r\n\t");
            @foreach(var post in posts) {
                 WriteLiteral("<div>");
                 Write(post.Title);
                 WriteLiteral("</div>");
                }
    WriteLiteral("\r\n</div>");
 }
}
}
 

最後,應用CodeDom API編譯上面的代碼,調用Execute方法輸出結果。設計

 

Razor API

一開始接觸這項技術時,覺得是ASP.NET MVC的一個開源項目,接觸以後才知道它是.NET Framework API中的類型,幾年沒有作Web開發,ASP.NET技術發展的確實很快。3d

System.Web.Razor.Parser.RazorParsercode

RazorParser用於解析腳本,可是它對Html,CS,VB腳本一無所知。MarkupParser用於解析Html標記,CSharpCodeParser用於解析包含C#代碼的標記,相應的VBCodeParser則用於解析包含VB腳本的標記,

System.Web.Razor.Generator.RazorCodeGenerator

根據傳入的Markup Parser,產生代碼。與Parser類似,它也有二個與標記語言相關的類型,CSharpRazorCodeGenerator 和VBRazorCodeGenerator,用於處理標記包含的腳本。

System.Web.Razor.RazorEngineHost

System.Web.Razor.RazorTemplateEngine

引擎宿主,用於接受標記腳本,產生.NET 類型的代碼。

把上面的內容綜合起來,寫一個例子程序,來看這些API的用法。

建立腳本宿主

var language = new CSharpRazorCodeLanguage();
var host = new RazorEngineHost(language) {
   DefaultBaseClass = "CustomTemplateBase",  
   DefaultClassName = "DemoTemplate",
   DefaultNamespace = "ProgrammingRazor",
};
 

添加Razor腳本引擎,讀取標記(Markup)文件

RazorTemplateEngine engine = new RazorTemplateEngine(host);
GeneratorResults razorResult = engine.GenerateCode("C:\\Script.txt");

編譯標記文件生成的類型,生成Code Dom 腳本

CompilerResults compilerResults =
new CSharpCodeProvider()
       .CompileAssemblyFromDom(
               new CompilerParameters(/*...*/),
               razorResult.GeneratedCode
);

執行生成的程序集類型,獲取結果

var template = (CustomTemplateBase)Activator.CreateInstance(「ProgrammingRazor.DemoTemplate」);
template.Execute();
 

Razor Pad程序的功能,也是用的這個基本思路來展來的。

Razor Pad是一個開放源碼的程序,你能夠從網址http://razorpad.codeplex.com中獲取它的源代碼。

相關文章
相關標籤/搜索