先說明遇到的狀況:我修改了單元測試專案Check In TFS,同事取回編譯測試時,出現NLog版本不合錯誤!專案需要3.1版,但實際卻是2.1版。
經初步檢查,疑點重重:
- 同一.sln還有其他專案,部分專案仍採用NLog 2.1版,出問題的單元測試專案使用NLog 3.1,但app.config有bindingRedirect設定要求全部改用3.1:
<dependentAssembly>
<assemblyIdentityname="NLog"publicKeyToken="5120e14c03d0593c"
culture="neutral"/>
<bindingRedirectoldVersion="1.0.0.0-3.1.0.0"newVersion="3.1.0.0"/>
</dependentAssembly>
依我的理解,有此設定,即便其他參照專案使用NLog 2.1,在單元測試專案裡也一律要強制改用3.1。莫非我一直以來的認知有誤? - 單元測試的bin\Debug\NLog.dll是2.1版,可以解釋版本不符的來源。但同一專案在我的機器上編譯、執行均無問題,在同事的機器上才出錯。
- NLog安裝自NuGet,檢查UnitTest.csproj,有以下設定:
<ReferenceInclude="NLog">
<HintPath>..\..\packages\NLog.3.1.0.0\lib\net45\NLog.dll</HintPath>
</Reference>
同時專案已啟動NuGet Package Restore,就算原本沒有也會自動下載安裝,更何況檢查packages目錄,NLog3.1.0.0\lib\net45\NLog.dll的確存在!
由以上觀察,怎麼都無法解釋單元測試專案為何使用2.1版,除非我的觀念有錯,這就可怕了!
攪和好一陣子,終於找出問題關鍵-同事跟我用的.sln不是同一個!!
先前因應專案位置調整,Boo.sln搬過家,我用的是新位置X:\TFS\Boo\Boo.sln,但舊檔未清,同事用到舊檔X:\TFS\Boo\Web\Boo.sln,而\TFS\Boo與\TFS\Boo\Web都有NuGet建立的packages資料夾。UnitTest.csproj於位\TFS\Boo\Web\UnitTest,當我參照NLog 3.1時,相對路徑..\..\packages指向\TFS\Boo\packages;同事取得新版時的確也還原下載了NLog 3.1,但pacakges跟著.sln,NLog 3.1被裝在\TFS\Boo\Web\packages下,而\TFS\Boo\packages只有先前安裝的2.1。我們在比對檢查時未察覺此一差異,直覺認定NLog 3.1存在,卻沒發現檢查的目錄並非UnitTest.csproj要參照的TFS\Boo\packages。由於csproj的NLog參數設定未指定版本,當<HintPath>提示路徑找不到,而其他專案包含NLog 2.1,VS編譯時使採用2.1版順利過關,但app.config有bindingRedirect設定,在執行階段才發揮作用,強制要求改用3.1版,碰!(跟上回VS可以編譯但在IIS爆炸如出一轍,未來遇到可編譯但執行階段才冒出的版本錯誤,應優先朝此方向偵辦)
詭異現象有了合理的解釋,幸好只是烏龍一場而非長期以來的觀念有誤,可喜可賀!