-
因為伺服器的效能有限,發現自從使用了Castle + Nhibernate 之後,伺服器在更新web站點之後的重新編譯過程特別漫長,有時都超過了1分鐘,儘管發布的web程式也是編譯好的。下面是web使用的動態函式庫:
Castle.Core.dll
Castle.DynamicProxy2.dll
Castle.Facilities.AutomaticTransactionManagement.dll
Castle.Facilities.NHibernateIntegration.dll
Castle.MicroKernel.dll
Castle.Services.Transaction.dll
Castle.Windsor.dll
FredCK.FCKeditorV2.dll
Iesi.Collections.dll
log4net.dll
MySql.Data.dll/System.Data.SQLite.dll
NHibernate.dll
UrlRewritingNet.UrlRewriter.dll
每次我的web專案有更新重新編譯後產生的web.dll上傳到伺服器,伺服器w3p就會重啟,csc我的web目錄下的文件,整個過程真是漫長的無法忍受。
[不知道各位大俠有沒有什麼好的建議]
後來想到把上面的那些動態庫放入GAC 中,會不會減少重啟需要時間(實踐證明沒有明顯的變化)。
本文沒有解決當初的問題,但是因為涉及到一個在asp.net 中引用存放在GAC中的第三方動態庫的問題,所以還是記錄下來(:-)這才是本文重點)。
上面所有的動態函式庫都是簽過名的,放入GAC的過程:
1. 註冊第三方動態庫入GAC
gacutil -i Castle.Core.dll
gacutil -i Castle.DynamicProxy2.dll
gacutil -i Castle.Facilities.AutomaticTransactionManagement.dll
gacutil -i Castle.Facilities.NHibernateIntegration.dll
gacutil -i Castle.MicroKernel.dll
gacutil -i Castle.Services.Transaction.dll
gacutil -i Castle.Windsor.dll
gacutil -i FredCK.FCKeditorV2.dll
gacutil -i Iesi.Collections.dll
gacutil -i Intelligencia.UrlRewriter.dll
gacutil -i log4net.dll
gacutil -i MySql.Data.dll
gacutil -i NHibernate.dll
gacutil -i System.Data.SQLite.dll
gacutil -i UrlRewritingNet.UrlRewriter.dll
這個過程比較容易,gacutil 可以在.net framework 的sdk 下找到(再分發包)
2. 重新定義web專案對第三方動態函式庫的引用方式:直接引用GAC
這裡遇到另一個問題, vs2005中無法引用到自己定義到GAC的第三方動態函式庫,除非做如下設定:
假設自己定義的第三方動態庫存放於: c:3rdlibs
修改登錄:HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFrameworkAssemblyFolders
在這個項目下加入一個項,並指向c:3rhlibs
現在可以在我們的web專案中引用第三方的GAC庫了。
3.重新編譯web,調試:
第一個問題:配置錯誤
view plaincopy to clipboardprint?
配置錯誤
說明: 在處理向該要求提供服務所需的設定檔時發生錯誤。請檢查下面的特定錯誤詳細資訊並適當地修改設定檔。
分析器錯誤訊息: 未能載入檔案或組件「UrlRewritingNet.UrlRewriter」或它的某一個依賴項。系統找不到指定的檔案。 (web.config line 50)
來源錯誤:
行48:
行49:
行50:
原始檔: web.config 行: 50
設定錯誤說明: 在處理向該要求提供服務所需的設定檔時發生錯誤。請檢查下面的特定錯誤詳細資訊並適當地修改設定檔。
分析器錯誤訊息: 未能載入檔案或組件「UrlRewritingNet.UrlRewriter」或它的某一個依賴項。系統找不到指定的檔案。 (web.config line 50)
來源錯誤:
行48:
行49:
行50:
原始檔: web.config 行: 50
顯然我們的web專案沒有找到已經存放在GAC 中的庫。放入GAC以前這些函式庫是跟隨編譯輸出到web/bin 目錄下的。現在自動定位不到,我們可以修改web.config 來指定函式庫的引用方式:
view plaincopy to clipboardprint?
.....
... ...
.....
... ...
再次編譯偵錯運行
第二個錯誤:編譯錯誤
view plaincopy to clipboardprint?
“/”應用程式中的伺服器錯誤。
-------------------------------------------------- ------------------------------
編譯錯誤
說明: 在編譯向該請求提供服務所需資源的過程中發生錯誤。請檢查下列特定錯誤詳細資訊並適當地修改原始程式碼。
編譯器錯誤訊息: CS0012: 類型「Castle.Windsor.IContainerAccessor」在未被引用的程式集中定義。必須加入程式集「Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc」的引用。
來源錯誤:
[沒有相關的來源行]
原始檔: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaaa.0.cs 行: 133
“/”應用程式中的伺服器錯誤。
-------------------------------------------------- ------------------------------
編譯錯誤說明: 在編譯向該請求提供服務所需資源的過程中發生錯誤。請檢查下列特定錯誤詳細資訊並適當地修改原始程式碼。
編譯器錯誤訊息: CS0012: 類型「Castle.Windsor.IContainerAccessor」在未被引用的程式集中定義。必須加入程式集「Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc」的引用。
來源錯誤:
[沒有相關的來源行]
原始檔: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaaa.0.cs 行: 133
這次是編譯錯誤,但是錯誤的資訊並不清晰,暫時無法定位到具體內容,修改web.config, 增加一個配置節(compilation),如下
view plaincopy to clipboardprint?
... ...
... ...
... ...
... ...
再調試:
view plaincopy to clipboardprint?
編譯錯誤
說明: 在編譯向該請求提供服務所需資源的過程中發生錯誤。請檢查下列特定錯誤詳細資訊並適當地修改原始程式碼。
編譯器錯誤訊息: CS0012: 類型「Castle.Windsor.IContainerAccessor」在未被引用的程式集中定義。必須加入程式集「Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc」的引用。
來源錯誤:
行134: }
行135:
行136: protected ASP.global_asax ApplicationInstance {
行137: get {
行138: return ((ASP.global_asax)(this.Context.ApplicationInstance));
原始檔: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaaa.0.cs 行: 136
編譯錯誤說明: 在編譯向該請求提供服務所需資源的過程中發生錯誤。請檢查下列特定錯誤詳細資訊並適當地修改原始程式碼。
編譯器錯誤訊息: CS0012: 類型「Castle.Windsor.IContainerAccessor」在未被引用的程式集中定義。必須加入程式集「Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc」的引用。
來源錯誤:
行134: }
行135:
行136: protected ASP.global_asax ApplicationInstance {
行137: get {
行138: return ((ASP.global_asax)(this.Context.ApplicationInstance));
原始檔: c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET FilesrootxxxxxxyyyyyyyyApp_Web_default.aspx.zzzzzzz.aaaaaaaa.0.cs 行: 136
這個錯誤訊息最重要:
編譯器錯誤訊息: CS0012: 類型「Castle.Windsor.IContainerAccessor」在未被引用的程式集中定義。必須加入程式集「Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc」的引用。
顯然,我們在修改web.config之後,iis服務重啟了當前的web項目,並且對它進行了編譯,首先被編譯的就是global.asax.cs, 其中某個初始化的變量,也可能是一個靜態的變量,調用了Castle.Windsor,並且csc 找不到這個Castle.Windsor ,真是一個麻煩的過程。
第一個嘗試: 在web專案中的引用部分,對Castle.Windsor 做設定,原來直接引用動態函式庫的時候是同步輸出到web/bin 下的,引用GAC之後此輸出就取消了,現在重新設定為「複製到本地」。當然,設定後的編譯會將此檔案:Castle.Windsor輸出到web/bin下,如此一來,偵錯也可以通過了,因為他找到了這個動態函式庫。
但這並沒有解除我們的疑惑,那就是,
第二個嘗試:想到第一個嘗試中的(compilation) 節,查看msdn的說明,知道
view plaincopy to clipboardprint?
然後取消web專案中對Castle.Windsor 的“複製到本機”,重新編譯運行。
All are Working Fine.
到這裡我們已經成功的把所以第三方引用的動態函式庫放入GAC 了