在 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&qu