Discuz!NT程式碼閱讀筆記(7)--模板初探:生成的模板是怎樣執行的

weixin_34219944發表於2010-05-20

相關連結:

Discuz!NT程式碼閱讀筆記(1)--從HttpModule開始:首頁的顯示

Discuz!NT程式碼閱讀筆記(2)--網站安裝也能自動化:論壇程式安裝及初始化過程

Discuz!NT程式碼閱讀筆記(3)--網站安裝也能自動化(2)--DNT安裝時使用到的幾個函式解析

Discuz!NT程式碼閱讀筆記(4)-- 一切皆可配置:頁面的顯示

Discuz!NT程式碼閱讀筆記(5)-- 從全域性看看:各個模組功能摘要

Discuz!NT程式碼閱讀筆記(6)-- 從全域性看看:各個模組功能摘要(2)

 

DNT介面顯示原理,來自官方

 

1ASP.NET內聯編碼編譯時間問題

         先說下我的一個試驗:

新建一個WebApplication工程,開啟Default.aspx檔案,刪除除<%@ Page Language="C#" AutoEventWireup="true" EnableViewState="true"  Inherits="Test2010._Default" %>

之外的內容。之後在它的下邊新增如下程式碼:

<%@ Page Language="C#" AutoEventWireup="true" EnableViewState="true"  Inherits="Test2010._Default" %>

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Text" %>

<script runat="server">

    protected override void OnInit(EventArgs e)

    {

        base.OnInit(e);

        StringBuilder bld = new StringBuilder();

        bld.Append("abc");

        bld.Append("<script type=\"text/javascript\"");

        bld.Append("\">alert('abc')</");

        bld.Append("script>\r\n");

        Response.Write(bld.ToString());

        Response.Write(sss());  

    }

 

    public string sss()

    {

        return " abcdefg";

    }

</script>

編譯,釋出。開啟發布後的網站,在Bin資料夾中可以看到生成的DLL。用Reflector開啟這個DLL後,可以發現沒有我在頁面中新增的sss()這個函式。

檢視釋出後的頁面檔案,可以看到頁面檔案中的內容與釋出前沒有任何不同,說明頁面內聯的程式碼在深層和釋出時都沒有被編譯。

       但是,與其相對應的Cs檔案卻沒有了。它已經被編譯到DLL中去了。這一點,通過Reflector可以很清楚地看到。

F5執行這個專案,在瀏覽器檢視Default.aspx的原檔案,可以看見只有這麼一行東西:

abc<script type="text/javascript"">alert('abc')</script>

abcdefg

這是已經被編譯後輸出到瀏覽器的程式碼。內聯頁面內的程式碼此時已經被解析過了。

於是,有一個結論:頁面內聯的程式碼是在執行時進行解析的(或者叫編譯,我不知道究竟該怎麼叫它)。

2、看看DNT的頁面檔案

         DNTUI是基於模板機制的。模板都存放在Discuz.Web工程中的Aspx資料夾中。每個模板主題一個資料夾。

         檢視這些模板中的頁面檔案,可以看見每個頁面中都有如下的組織結構:

<%@ Page language="c#" AutoEventWireup="false" EnableViewState="false" Inherits="指示了隱藏的程式碼類" %>

<%@ Import namespace="System.Data" %>

<%@ Import namespace="Discuz.Common" %>

<%@ Import namespace="Discuz.Forum" %>

<%@ Import namespace="Discuz.Entity" %>

 

<script runat="server">

override protected void OnInit(EventArgs e)

{

 

    /*

        This page was created by Discuz!NT Template Engine at 2009-9-22 17:25:25.

        本頁面程式碼由Discuz!NT模板引擎生成於 2009-9-22 17:25:25.

    */

 

    base.OnInit(e);

 

    templateBuilder.Capacity = 220000;

//……省略中間內容……..

    Response.Write(templateBuilder.ToString());

}

</script>

這裡,首先使用StringBulider templateBuilder組織需要頁面內容,然後通過Response.Write(templateBuilder.ToString());將組織好的內容輸出到Http響應的輸出流中。經過IIS解析後(也可能是CGI之類的東西,我沒查到),發給客戶端,顯示在瀏覽器中。

這樣的程式碼釋出後依然包含在頁面檔案中。後邊新增的模板,也是這樣的結構,他們共用一個已經編譯好的存放在DLL中的頁面類。這些Aspx檔案中的東西只有等到需要時才被編譯。據說這種做法可以在程式編譯好後為程式新增模板。

DNT有自己的後臺專案Discuz.Web.Admin包含了自動生成模板的功能。它可以根據使用者定義好的css檔案,生成論壇可以用的模板,輸出的同樣是具有這種結構的Aspx檔案。這樣,不同的DNT模板就可以共用一個cs檔案,即編譯在DLL檔案中的頁面類。終端使用者只需要定義模板顯示的方式(CSS),而不需要去花時間理解頁面內的各種函式。即使不理解Asp.Net,也能定義出漂亮的模板了。

 

Technorati 標籤: DNT

相關文章