目錄
前言
Asp.net 發布分為:動態編譯和預編譯。預編譯又分為:In Place Pre-compilation 和 Pre-compilation for Deployment。關於asp.net編譯,推薦Artech寫的:
深入剖析ASP.NET的編譯原理之一:動態編譯(Dynamical Compilation)
深入剖析ASP.NET的編譯原理之二:預編譯(Precompilation)
本文講述的編譯都是預編譯中Pre-compilation for Deployment的Updatable Pre-compilation。如圖所示:

開始
來到新公司的這段時間,經常聽到同事們抱怨:只是改了幾個頁面,每次都要將整個網站發布一遍,然后從上百個文件中仔細的挑選自己改的那幾個頁面。
仔細想想,以前開發的網站都是客戶定制的,網站一交付,基本就不會再修修改改了,或者根本就不發布網站,直接把源碼放到IIS中,故不會頻繁發布網站。
來到新公司之后,開發的是公司自己的在線產品,經常需要對網站升級、修改,因而需頻繁的發布網站。
對需要頻繁發布網站的團隊來說,vs自帶的發布網站工具,帶來的痛苦有:
a、每次需整個發布一遍,特別耗時間。頁面越多,預編譯就越慢。
b、需要仔細挑出自己修改過的aspx頁面和bin下對應的dll文件。同樣是:頁面越多,越不容易找到,特別是dll。
聽說博客園博客程序中.aspx和.ascx文件總共加起來有3000多個,使用fixednames編譯需要30分鍾,呵呵~~
那怎么辦呢?
以下提供兩種解決方法:
aspx.cs文件放到單獨的類庫項目
將所有的aspx.cs文件集中放到同一類庫項目下,意味着你攬了ASP.NET預編譯的活。也就是說預編譯給每個頁面生成的代碼,你需要自己手寫。
先來對比一下正常發布,頁面文件內容的變化:
Web.config設置:

Default.aspx:
發布前:

發布后:

Default.aspx.cs:
發布前:

發布后(用.Net Reflector打開bin目錄下對應的dll):

由此可見,預編譯做的工作:
-
為每個頁面單獨生成一個dll,並在class中為頁面上所有服務端空間,聲明一個以id命名的控件全局變量。(頁面中不用服務端控件,全部是原生的html開發,此可忽略)
-
解析web.config中的設置。例如:page節點、profile節點。(可以用基類代替page節點設置,可以用全局變量代替profile設置,或者寫到appsetting節點下)
-
編譯global.asax成App_global.asax.dll。(不用global.asax,所有的事件方法都是在HttpModule中定義)
-
編譯app_code成app_code.dll。web.config中的Profile節點生成在app_code中的ProfileCommon中。(基本沒用過profile,通常使用公共靜態屬性代替)
Demo:
-
打開vs,新建一個網站。
-
添加一個類庫項目:AspxCsCode,並添加System.Web的引用
-
為網站添加類庫項目的引用。
-
以上述Default.aspx為例,將Default.aspx.cs剪切到AspCsCode項目中。如下圖:
-
修改Default.aspx.cs代碼:

-
修改Default.aspx

-
生成網站。在瀏覽器中查看default.aspx
點擊登錄è
總結
優點:
-
aspx與cs分離了。aspx完全可以交給前端工程師,Cs交給后端工程師,分工更明確,開發效率更高。
-
支持單元測試。以往開發頁面,想測試aspx.cs中某個方法,只能瀏覽頁面。如果放到類庫項目下,單元測試將變得很方便
-
網站發布時很快。編譯類庫項目是相當快的。如果沒用到Global.asax和App_Code的話,基本上都不需要發布了。
缺點:
-
攬了ASP.NET預編譯的活。如果項目中不用服務端控件,這個基本可以忽略
-
發布的時候,有覆蓋他人頁面的風險。跟團隊成員討論,部分人覺得,把所有頁面的cs文件放到一個類庫項目中,
當我修改了a.aspx.cs,b.aspx.cs也被別人修改時或者還沒有被簽入,我沒有獲取最新版本,然后就把類庫編譯成的dll,更新到服務器上從
而會出現問題,更偏好Asp.net預編譯生成的一個頁面對應一個dll的方式,只發布自己改的文件,將影響面積降到最低。
個人覺得這個缺點的理由不夠充分,既然要發布,那就必須保證你編譯的所有代碼版本不應該比服務器上的版本低,
如果這個保證不了,那怎么能保證頁面引用的其他dll是最新的呢,而且如果照上述邏輯,
asp.net mvc豈不是也有這種情況?給每個cs都單獨生成一個dll豈不更好?
故而認為,不管哪種方式都有覆蓋他人代碼的風險,只是這種方式風險稍微大些。
一個可選擇勾選頁面的發布工具:LimusicAddin
aspx.cs文件放到單獨的類庫項目其實是一種變通的方法,本質上並沒有解決vs自帶的發布網站工具每次都要預編譯整個網站的缺陷。那只能自己開發個插件了。
詳細介紹:
可發布指定的ASP.NET頁面的插件:LimusicAddin
