ASP.NET中的動態編譯
1.為什么要進行預編譯
ASP.NET 2.0的編譯方式大體可以分成兩種:動態編譯和預編譯,要回答為什么要進行預編譯,我們先要看看動態編譯有什么不好的地方。我們回顧一下上一篇介紹的ASP.NET進行動態編譯的簡單的流程:當來自Brower的一個基于aspx的Http request抵達Web server,IIS handle這個request,通過分析注冊在IIS中的Application Mapping,將Request 傳給aspnet_isapi.dll ISAPI extension。ISAPI extension通過HttpRuntime進入Http Runtime Pipeline,HttpRuntime為每個Request創建一個單獨的HttpContext對象,用于保存request的Context信息。在Http Runtime Pipeline中,Http request會被注冊的一系列的Http module處理,比如OutputCache Module,Session Module,Authentication Module,Authorization,ErrorHandler Module等等。在Pipeline的終端,ASP.NET需要需要根據request創建對應的HttpHandler對象來處理該Request,并生成結果Response到Client。對于一個基于Aspx的Http request,對應的Http handler對象一般就是一個System.Web.UI.Page對象。
ASP.NET會先判斷對應的Page type是否存在于被Cache的Assembly中,如果存在,直接創建Page對象,否則ASP.NET會先對該Page的相關的Source code (包括code behind,html等等) 進行編譯,我們也說過這種編譯是一Directory為單位的,也就是說,處于同一個Directory下的需要編譯的文件會被編譯成到同一個 Assembly中。編譯生成的Assembly會被Cache,用于后續的Request。
正是因為對資源的首次訪問會導致一次編譯(這樣說不太準確,因為動態編譯是以directory為單位進行的,應該對對某個Directory下的資源進行首次訪問),這樣會嚴重降低Web Application的響應速度。所以我們為了避免這種情況,需要預先對web site進行編譯,所以提高web site的響應是進行預編譯的最重要的原因。
同時動態編譯就以為著Web server上放置的是Source code,而且他們是可被修改的。而對于一個開發完畢的Web Application,我們更希望以Binary Assembly的方式進行部署,這樣Server上部署的都是Binary Assembly,不怕被別人篡改而導致系統的崩潰,從知識產權來講,也更利于保護商業秘密。這也是我們為什么要進行預編譯的另一個原因。
下面我們就來講講如何進行預編譯,以及與編譯背后的原理。同時在這里我需要特別提出的是,在上一部分講的一些術語和原理,比如Preservation file,FastObjectFactory,同樣適用于預編譯,重復的內容,在這里就不必再介紹了。同時我也將沿用上一部的Sample。如果想看看相關的內容,請參閱[原創]深入剖析ASP.NET的編譯原理之一:動態編譯(Dynamical Compilation)。
2.In Place Pre-compilation V.S. Pre-compilation for Deployment
對于預編譯,有可以分為In Place Pre-compilation和Pre-compilation for Deployment,In Place Pre-compilation很簡單,實際上就是把整個Web site編譯到我們一個臨時的目錄下面,這個臨時目錄也就是我們在介紹動態編譯提到的那個臨時目錄。而且這個編譯的方式,包括生成的文件也和動態編譯完全一樣,唯一不同就是編譯的時間:預先編譯,編譯的范圍:整個Web site。這種編譯就是你常用的在VS的build。這種編譯方式一般用于開發階段。
為了部署為目的的編譯是我們今天討論的重點,下面我們就著重來討論Pre-compilation for Deployment。
注:在ASP.NET的編譯都是通過一個叫做 aspnet_compiler的工具執行的,該工具隨ASP.NET 2.0一起發布,你完全可以利用此工具以命令行的方式的執行編譯,并通過傳遞不同的命令行開關設置不同的編譯選項。該工具被置于了VS中,使你可以利用 VS進行可視化的編譯。
3.Non-updatable Pre-compilation V.S. Updatable Pre-compilation
ASP.NET 2.0為我們提供了幾種不同方式的預編譯和部署。為了弄清楚這些預編譯和部署方式,我們先來回顧一下ASP.NET 1.x下的編譯方式。我們知道在ASP.NET 1.x時代對整個Web site進行編譯,實際上我們只會對所有C#和VB.NET等后臺代碼進行編譯,并生成一個單一的Assembly。而Web page的aspx是不會參與編譯的。所以當我們訪問一個Web page的時候,ASP.NET必須對aspx進行動態編譯。
- <%@PageLanguage="C#"AutoEventWireup="false"
- Codebehind="Default.aspx.cs"
- Inherits="Default"%>
- publicpartialclassDefault:System.Web.UI.Page
- {
- protectedvoidPage_Load(objectsender,EventArgse)
- {
- }
- }
【編輯推薦】