分享
 
 
 

ASP.NET中共用代码

王朝asp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在 ASP.NET中 動態共用原始碼

作者:鄭子璉

2004 年 11 月

在 ASP.NET 中由於可直接使用或替換 DLL 檔,大部分人較不關心動態共用原始碼的問題,由於 ASP.NET 在執行時可動態編譯最新原始碼供網站執行,是否一定要採用 DLL 來執行網頁對於管理者來說,沒有絕對的準則,但對系統或程式設計師來說,動態共用原始碼意味相同原始碼可供各專案同時共用,當在開發或維護某一專案時,針對共用原始碼的變動,亦等同於針對所有專案一起更新,此外亦可降低相同功能類似原始開發維護時間,有助於開發力的提升及專案小組共同開發。

例如早期專案存取資料庫可能以 OLEDB 開發,而到 .Net framework 1.1 納入 ODBC 後,在開發新專案時,於共用程式碼可加入 ODBC 支援,則原先專案亦同時獲得 ODBC 支援效益。

在 ASP.NET 中動態共用原始碼有三種方法:

使用 Web 使用者控制項 (*.ascx)使用程式碼宣告區塊伺服器端Include指示詞語法在線上手冊或相關 ASP.NET 叢書中多半都介紹到 Web 使用者控制項,因此本文不重複介紹,而方法 2、方法 3 可參考的資料極少,可參考文末其他參考資訊所列網址。在上述方法中,Web 使用者控制項是屬於使用者介面共用,程式碼區塊或 Include 指示詞則屬於類別、模組或 HTML 等語法共用,在用途及分類上亦有所不同。

首先建立一個測試範例,將原始碼切割為四個檔案部份,如圖 1,程式碼如下:

圖 1 Test.aspx

<%@ Page Language="vb" AutoEventWireup="false" %>

<script language=vb runat=server src="testClass.vb" /%>

<!-- #include virtual = "Include.aspx" --%>

testClass.vb

Public Class testClass

Public Function Test() As String

Return TypeName(Me) & ": testClass.vb Function"

End Function

End Class

Include.aspx

<script language=vb runat=server src="testFun.vb" />

<script language=vb runat=server id="modInclude">

Function Test1()

Response.Write(TypeName(Me) & ": Include.aspx Function Test1" & "<br>")

End Function

</script>

<%

Dim cTest As New testClass

Test1()

Test2()

Response.Write(cTest.Test() & "<br>" & vbNewLine)

%>

testFun.vb

Public Function Test2()

Response.Write(TypeName(Me) & ": testFun.vb Function Test2" & "<br>")

End Function

Test.aspx 是實際的網頁,其他三個檔都是示範動態共用的引入檔,引入外部原始碼之語法有兩種:

使用程式碼宣告區塊 <script language="codelanguage" runat="server" Src="pathname" />

在本區塊內的原始碼,可建立物件類別、列舉等,並可與 Visual Basic .Net 共用原始碼,例如本例中 testClass.vb。在 Web Form 内不能建立新的模組類別,故如 testFun.vb 不能另外使用 Module…End Module。在物件類別中,由於屬於內含類別,故檔案內不能直接存在任何屬於網頁部分的原始碼,若要使用 Visual Studio .Net IDE 環境(以下簡稱 VS.NET)編輯原始碼,建議在使用程式碼宣告區塊時以物件類別為主,以避免 VS.NET 提示錯誤。

伺服器端 Include 指示詞語法 <!-- #include file | virtual = filename -->

此種方式如同原先 ASP 引入檔案方式,由於屬於 ASPX 原始檔的一部份,因此在檔案內可使用屬於網頁部分的相關設定,亦可再引入其他原始碼。若要使用 VS.NET 編輯原始碼,建議副檔名取為 .aspx,則可使用 VS.NET 提示錯誤、自動感知及連結線上說明功能。

在測試範例時,為了確保原始碼為動態引入,請不要使用 VS.NET 中執行的功能,才不會自動依照應用程式建立 DLL 檔參照,導致不易分辨函數或物件功能是否由原始碼引入,因此請直接由 Internet Explorer(以下簡稱 IE)網址列直接輸入對應網址 http://localhost/Include/test.aspx。此外,由於並未透過 VS.NET 進行編譯,因此無法繼承 DLL 檔內之物件,若使用 VS.NET 創建本範例時,請手動移除 Global.asax 及每一個 Web Form (*.aspx) 原始碼中,Inherits 的屬性,才不致發生問題。

在此範例中,將網頁主要顯示內容的程式碼分隔放置在 Include.aspx 內,並呼叫各函數或建立物件,在 IE 上顯示結果如圖 2,一個簡易的動態共用原始碼就此成形,若各部分程式碼有修正,只要重新整理 IE,即可依修正後的程式碼顯示網頁,在網頁系統維護與專案開發將可獲得不小的彈性。

圖 2 更進一步在內含類別中可能會想要共用其他部分的的變數或函數,此時會發現不能直接在內含類別中使用,想要使用的方法有三種:

以 Shared 關鍵字宣告變數或函數將主物件當作變數傳遞宣告一個主物件引用在原先範例中加入 Shared.aspx 來測試,因此 Test.aspx 也小幅修改來進行測試,修改部分程式碼加上底線來區別。修改過後的程式碼執行成果如圖 3 所示。

Test.aspx

<%@ Page Language="vb" AutoEventWireup="false" ClassName="myTest" %>

<script language=vb runat=server src="testClass.vb" />

<!-- #include virtual = "Shared.aspx" -->

<!-- #include virtual = "Include.aspx" -->

Shared.aspx

<script language=vb runat=server id="modShared">

Public Shared shdMe As Object

Public Shared shdString As String = ""

Public Class cTestObj

Public Function Test(Byval commonObj As Object)

Return commonObj.PublicFun(SharedFun("cTestObj"))

End Function

End Class

Public Class cTestShd

Public Function Test()

Return shdMe.PublicFun(SharedFun("cTestShd"))

End Function

End Class

Public Class cTestName

Public Function Test()

Dim webTest As New myTest

Return webTest.PublicFun(SharedFun("cTestName"))

End Function

End Class

Public Function PublicFun(Byval strOutput As String)

shdString &= "-[Public]"

Return strOutput & "-[Public]"

End Function

Public Shared Function SharedFun(Byval addString As String)

shdString &= addString & "-[Shared]"

Return addString & "-[Shared]"

End Function

</script>

<%

shdMe = Me

Dim clsObj As New cTestObj

Response.Write(clsObj.Test(Me) & "<br>")

Dim clsShd As New cTestShd

Response.Write(clsShd.Test() & "<br>")

Dim clsName As New cTestName

Response.Write(clsName.Test() & "<br>")

Response.Write(TypeName(shdMe) & ", " & shdString & "<br>")

%>

圖 3 以 Shared 為關鍵字宣告 當變數或函數以 Shared 為關鍵字宣告為共用後,變數及函數將變更為全域靜態,本例中宣告共用一個物件變數、一個字串變數及一個函數,由於變數為靜態變數,在所有工作階段 (Session) 連線未結束前可以疊加,因此字串變數宣告同時指定初值來避免疊加,但使用若需有類似變數需在網頁系統中共用時,不一定需要使用 Session 物件。共用函數則可於物件中直接使用,不需考慮命名空間的問題。

將主物件當作變數傳遞 傳遞物件可以透過引數或使用前述共用變數傳遞,在 cTestObj 類別中,將物件以引數方式傳遞到物件內使用,在 cTestShd 則透過共用變數傳遞到類別內。由於 PublicFun 函數為主物件下之公用函數,因此須透過主物件命名空間叫用。

宣告一個主物件引用 在cTestName 類別中,示範宣告一個主物件使用,這裡面會產生一個困擾,主物件類別的名稱為何?在本文中所有的程式碼都是被 Test.aspx 引入,對 ASP.NET 來說,實際上只是當作一個 aspx 檔來處理,所以在物件名設定上只能有一個,即是以 Test.aspx 設定為依據。在 Test.aspx 修改例中,在第一行加入 ClassName 指示詞的屬性,這邊指定的類別名稱即可在 cTestName 類別中使用,若是未指定類別名稱,則預設以該 Web Form 檔名將小數點 (dot) 替換為下減號 (under line) 後為預設物件名稱,如圖 2 中,Test_aspx 為物件名稱,圖3中則顯示 myTest 為物件名稱。當然在 cTestName 類別中可以宣告為 Test_aspx 物件,但通常可能因為共用的理由而不知道是哪個 Web Form 引用,在此情況下規定物件名會比較方便。

其他特性來說,在 Shared.aspx 及 Include.aspx 內分別存在程式碼轉譯區塊 (<% … %>),此特性亦有助於在不同分離的共用程式碼檔內,載入時執行指定程式碼或宣告特定的變數,例如在資料庫存取程式碼的規劃上,可將連線字串或常數分割在一個原始碼檔內,連線查詢的程式碼則分割在另一個原始碼檔內,不同的專案或不同的資料庫只要分別建立對應的連線字串宣告即可,仍可引用共用的程式碼存取資料庫。

此外,經由Shared宣告後的變數為靜態共用,在多使用者同時登入的環境下,亦可考慮透過 Shared 變數交換訊息,例如聊天室內的文字字串屬於不斷累加,即可使用 Shared 變數來達到效果。

最後要測試的是動態共用原始碼的限制。使用程式碼宣告區塊時,由於已無法在此區塊內再引用其他程式碼,故引用深度僅一層。使用 Include 指示詞時,由於下層的引入檔仍可繼續使用 Include 指示詞,所以並不知道最大可用深度。一般來說,深度測試屬於串聯測試,廣度測試屬於並聯測試,而通常深度限制比廣度限制來得嚴峻(遞迴深度),因此僅做最大深度測試。首先以程式產生輸出下面的程式碼到不同的檔案,n 由 1 ~ 10,000 進行深度測試,為了確認每個檔案均能被執行到,故在每個檔案內均使用程式碼轉譯區塊執行該檔的輸出函數,串接的結構圖如圖 4 所示。

loop[nnnnn].aspx

<script language=vb runat=server>

Public Function Responseloop[nnnnn]()

Response.Write("loop[nnnnn]<br>")

End Function

</script>

<% Responseloop[nnnnn]() %>

<!-- #include virtual = "loop[nnnnn+1].aspx" -->

圖 4 測試電腦作業系統為 Windows XP SP2,配備為 P4 1.6G/384 MB,在測試電腦中 n 介於 4,650 ~ 4,800 間,但是大量引用檔案下,在動態編譯時非常耗損記憶體,在測試 n=4,650 時,編譯時期記憶體使用量暴增 460 MB 左右 (aspnet_wp.exe),與原先開機中執行其他程式使用記憶體約 400 MB 相加後,達到測試電腦虛擬記憶體上限,或許在等級更高的電腦中,可以再稍加擴增深度。在測試 n=4,800 時,此時記憶體尚未達到上限,即跳出圖 5 的錯誤,並且 ASP.NET 之服務程式 (aspnet_wp.exe) 會發生異常終止,並將錯誤訊息寫入事件簿後重新啟動 ASP.NET 服務程式,因此可以推定在 ASP.NET 1.1 下,最大深度不超過 4,800。

圖 5 (註:圖中被人工遮罩之文字字串為本機電腦名。) 原則上深度超過 10 以上來說,對於一般人思考邏輯能力是較高的挑戰,一般程式設計也不會將深度無限制擴增,多半深度仍在 10 以內,故目前測試最大深度超過 4,650,對絕大多數的管理與維護而言,已遠超過設計需求。

本文討論動態共用原始碼可對中大型系統設計與管理維護提供另一方向,平時運用可考慮以網頁系統設計師為主,散佈或結案時依委託契約要求,而採原始碼或DLL檔交付,在多系統共用原始碼的情況下,亦可減少原始碼開發成本,提升原始碼管理與維護的能量,個人或開發小組所創建的類別程式庫或函數程式庫均可採用此方法管理維護,達到快速開發網頁系統的目的。

其他參考資訊:程式碼宣告區塊:

http://msdn.microsoft.com/library/CHT/cpgenref/html/cpconCodeDeclarationBlocks.asp

伺服器端 Include 指示詞語法:

http://msdn.microsoft.com/library/CHT/cpgenref/html/cpconServer-sideIncludeDirectiveSyntax.asp

作者簡介:

個人網站:http://tlcheng.adsldns.org/TLCheng/

任職於水海科技系統研發驗證工作室/國立成功大學水利及海洋工程研究所博士候選人,獲選 2003、2004 微軟最有價值專家,參與開發國內水資源、防洪等模式並擬定相關法規條文,個人網站中提供 Basic/Fortran/ 輔助說明檔、/Windows API/Net 相關技術說明及原始碼及專業著作相關文章。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有