Dot-Net

.NET 程序集引用對我來說都是循環的

  • March 19, 2010

更新:昨晚,我認為更改保存某些報告的文件夾的工作量太大。我的解決方法是重命名文件夾,執行我需要完成的批處理作業,然後將文件夾名稱改回原來的名稱。我覺得我可以把今天剩下的時間和下週的所有時間都花在這上面,但仍然沒有什麼可展示的。我寧願因為與我的老闆背道而馳,也不願不能向我們的客戶開具發票(這種情況每年只發生一次)。感謝所有幫助過的人,我為你願意幫助一些匿名的傢伙而感到謙卑。我不知道如何“放棄”這個問題,但仍然給你們提供道具,我會在午餐時閱讀常見問題解答和任何評論。謝謝你。

我正在嘗試調試我的前任創建的 ac# 應用程序。他是程序員,我是系統管理員,也許這就是我出錯的地方。

無論如何,我需要重新編譯其中一個程序集並將其部署到我們的生產伺服器。當我編譯它時,我得到了錯誤:

‘Mcrcsip.Web.McrcsipWebExceptionBase 類型在未引用的程序集中定義。您必須添加對程序集“Mcrcsip.Web, Version=2.0.3266.28977, Culture=neutral, PublicKeyToken=c3de6c6abcdf794b”的引用。

我碰巧有該程序集的副本,當我刪除對現有程序集的引用(具有不同公鑰令牌的 2.0.0.0)並添加對它所要求的程序集的引用時,當我編譯時,出現此錯誤資訊:

‘Mcrcsip.Web.McrcsipWebExceptionBase 類型在未引用的程序集中定義。您必須添加對程序集“Mcrcsip.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8bbdde85caf008d0”的引用。

如果我在Google上搜尋這個錯誤(當然是通用的),我會得到一堆“這就是你添加程序集引用的方式……”結果。

我該如何擺脫這個旋轉木馬?

以下是解決方案的佈局方式:

  • Mcrcsip.Amwa.Solution

    • http://amwa-test.internal.lan/

    • Mcrcsip.Amwa.Core

      • Mcrcsip.Aws.Bol
      • Mcrcsip.Common
      • Mcrcsip.Web
      • nunit.framework
      • 系統
      • 系統配置
      • System.Data
      • 系統.企業服務
      • 系統.Web
      • System.Web.Services
      • 系統.XML
    • Mcrcsip.Amwa.CrFactory

      • CrystalDecisions.CrystalReports.Engine
      • CrystalDecisions.Enterprise.Framework
      • CrystalDecisions.Enterprise.InfoStore
      • CrystalDecisions.ReportSource
      • CrystalDecisions.Shared
      • CrystalDecisions.Web
      • Mcrcsip.Amwa.Core
      • Mcrcsip.Web
      • 系統
      • 系統配置
      • System.Data
      • 系統繪圖
      • 系統.Web
      • 系統.XML
    • Mcrcsip.Amwa.PdfFormHandler

      • itextsharp
      • Mcrcsip.Amwa.Core
      • Mcrcsip.Web
      • 系統
      • 系統配置
      • System.Data
      • 系統.Web
      • 系統文件
    • Mcrcsip.Amwa.Web

      • Mcrcsip.Amwa.Core
      • Mcrcsip.Amwa.CrFactory
      • Mcrcsip.Amwa.PdfFormHandler
      • Mcrcsip.Aws.BOL
      • Mcrcsip.Common
      • Mcrcsip.SharePoint
      • Mcrcsip.Web
      • 系統
      • 系統配置
      • System.Data
      • System.EnterpriseServices
      • 系統.Web
      • System.Web.Services
      • 系統.XML
    • Mcrcsip.Amwa.WebControls

      • 系統
      • System.Data
      • System.Design
      • 系統繪圖
      • 系統.Web
      • 系統文件
    • Mcrcsip.Amwa.Setup

參考不一致或:我如何學會如何停止擔心並愛上 ILDASM

咳咳咳,

問題

缺口,

通過重新閱讀您的原始文章,很明顯您有一個 dll 版本不一致的問題。也就是說,您的解決方案中至少有一個項目依賴於 Mcrcsip.Web 版本 X,並且您的解決方案中至少有一個項目依賴於 Mcrcsip.Web 版本 Y

$$ or worse still, depends on a library that depends on Mcrcsip.Web version Y $$. 追踪這些可能既困難又乏味。 請參閱推薦的解決方案以跳到最後。

如何

當出現這種不一致時

  1. 您有一個依賴項,例如 A 依賴於 B 和 C,B 依賴於 C,
  2. A 和 B 最初是針對 C 版本 1 建構的,
  3. A 是針對 C 版本 2 更新和建構的,

與我們的直覺預期相反,當我們建構 A 時,B 不會自動更新為使用 C 版本 2。A 和 B必須引用同一個庫才能正確建構。所以要麼 A 必須符合 C ver 1,要麼 B 必須重建並符合 C ver 2。

現在,這可能發生在任何項目配置中,這就是為什麼對軟體進行版本控制很重要

$$ believe me this problem gets worse without proper signing\versioning $$,並在發生依賴項更新時在您的團隊內部進行良好的溝通。 還值得知道有兩種依賴引用,硬的和軟的

$$ in actual fact, they are the same, that is links to dlls, except one is a special case of the other, and conceptually it helps to distinguish the two $$. 硬引用

硬引用是項目對靜態 dll 的依賴。也就是說,依賴項是在特定時間建構的,除非將其物理文件替換為新文件,否則將永遠不會更新。硬引用通過添加引用對話框添加到解決方案,並從 .Net、COM 或瀏覽選項卡添加引用。硬引用通常用於向在目前解決方案範圍之外開發的軟體添加依賴項

$$ ie framework, third party, and other first party products developed by other internal teams $$. 硬引用也有變得陳舊的趨勢,因為它們是由自己的開發流維護和更新的。 假設上面的場景

  1. 您有一個依賴項,例如 A 依賴於 B 和 C,B 依賴於 C,
  2. A 和 B 最初是針對 C 版本 1 建構的,
  3. A 是針對 C 版本 2 更新和建構的,

此外,假設 A 和 B 在同一解決方案中

  • 簡單解決方案

    • 一個

      • 乙 $$ Hard reference $$
      • C v2$$ Hard reference $$
      • C v1$$ Hard reference $$

建構 A 後,您將收到您描述的錯誤。A 期望來自 C v2 的對象,但由於 B 對 C v1 有硬依賴,因此 C v1 會先載入到記憶體中,並發生衝突。A 期望 v2 並找到 v1。那是你的錯誤。

要解決這種情況,您必須

  1. 將項目 B 硬引用 C v1 更新為 C v2
  2. 強制重建項目 B
  3. 將項目 A 硬引用 B 更新為$$ newly built $$乙
  4. 強制重建 A

軟引用

軟引用是一個項目對同一解決方案中另一個項目的依賴關係。也就是說,每次重建整個解決方案時都會重建依賴關係。軟引用通過“添加引用”對話框添加到解決方案,並從“項目”選項卡添加引用。軟引用通常用於向在目前解決方案範圍內開發的軟體添加依賴項,它們的主要優點是在同一解決方案中對消費者進行更改時傳播更改。由於這個事實,軟引用不會過時。

$$ this is a special case of a hard reference, Visual Studio will add a reference that points to the output path of the target project, i believe it also updates this path if the target project changes its output configuration - but a very handy feature that warrants distinction $$ 假設上面的場景

  1. 您有一個依賴項,例如 A 依賴於 B 和 C,B 依賴於 C,
  2. A 和 B 最初是針對 C 版本 1 建構的,
  3. A 是針對 C 版本 2 更新和建構的,

此外,假設 A 和 B 在同一解決方案中

  • 簡單解決方案

    • 一個

      • 乙 $$ Soft reference $$
      • C v2$$ Hard reference $$
      • C v1$$ Hard reference $$

建構 A 後,您將收到您描述的錯誤。A 期望來自 C v2 的對象,但由於 B 對 C v1 有硬依賴,因此 C v1 會先載入到記憶體中,並發生衝突。A 期望 v2 並找到 v1。那是你的錯誤。

解決,

  1. 將項目 B 硬引用 C v1 更新為 C v2
  2. 強制重建 A

如您所見,軟引用更易於維護。

達斯馬

$$ Intermediate Language DisASeMbler $$ 既然您對引用和項目維護有了更多了解,那麼您究竟如何確定建構的狀態?畢竟,您的任何一個項目或其依賴項都可能不一致。

簡單的方法是打開您的建構輸出目錄,並檢查您的解決方案生成的每個 dll 的程序集清單。

要檢查程序集的清單,

  1. 打開ildasm.exe
  • 對於 VS2010,ildasm 可從快捷方式獲得
  • 對於 VS2008 和 VS2005,打開 Visual Studio 命令提示符,從命令行輸入“ildasm”
  1. 打開一個dll,
  • 點擊文件 -> 打開,或
  • 按 Ctrl-O,或
  • 將您的 dll 拖放到ildasm視窗中
  1. 打開清單
  • 點兩下標記為 MANIFEST 的紅色三角形節點
  1. 查找對 Mcrcsip.Web 的引用
  • 點擊查找並在對話框中輸入 Mcrcsip.Web,或
  • 按 Alt-F 並在對話框中輸入 Mcrcsip.Web,或
  • 手動檢查 MANIFEST 文件的內容
  1. 驗證版本號

這是乏味和痛苦的,但如果你遇到

$$ non-trivial $$dll不一致錯誤,這是找到它的唯一方法。 推薦解決方案

  1. 確保您的解決方案在適用的情況下使用軟引用,
  • 展開 Mcrcsip.Amwa.CrFactory

    • 展開參考
    • 刪除參考 Mcrcsip.Amwa.Core
    • 打開添加引用對話框
    • 從項目選項卡打開 Mcrcsip.Amwa.Core
  • 展開 Mcrcsip.Amwa.PdfFormHandler

    • 展開參考
    • 刪除參考 Mcrcsip.Amwa.Core
    • 打開添加引用對話框
    • 從項目選項卡打開 Mcrcsip.Amwa.Core
  • 展開 Mcrcsip.Amwa.Web

    • 展開參考
    • 刪除參考 Mcrcsip.Amwa.Core
    • 刪除參考 Mcrcsip.Amwa.CrFactory
    • 刪除參考 Mcrcsip.Amwa.PdfFormHandler
    • 打開添加引用對話框
    • 從項目選項卡打開 Mcrcsip.Amwa.Core
    • 從項目選項卡打開 Mcrcsip.Amwa.CrFactory
    • 從項目選項卡打開 Mcrcsip.Amwa.PdfFormHandler
  1. 確保您的解決方案在適用的情況下使用新的硬引用,
  • 展開 Mcrcsip.Amwa.Core

    • 展開參考
    • 刪除參考 Mcrcsip.Aws.Bol
    • 刪除參考 Mcrcsip.Common
    • 刪除參考 Mcrcsip.Web
    • 打開添加引用對話框
    • 從瀏覽選項卡打開 Mcrcsip.Aws.Bol$$ always best to specify location $$
    • 從瀏覽選項卡打開 Mcrcsip.Common
    • 從瀏覽選項卡打開 Mcrcsip.Web
  • 展開 Mcrcsip.Amwa.CrFactory

    • 展開參考
    • 刪除參考 Mcrcsip.Web
    • 打開添加引用對話框
    • 從瀏覽選項卡打開 Mcrcsip.Web
  • 展開 Mcrcsip.Amwa.PdfFormHandler

    • 展開參考
    • 刪除參考 Mcrcsip.Web
    • 打開添加引用對話框
    • 從瀏覽選項卡打開 Mcrcsip.Web
  • 展開 Mcrcsip.Amwa.Web

    • 展開參考
    • 刪除參考 Mcrcsip.Aws.Bol
    • 刪除參考 Mcrcsip.Common
    • 刪除參考 Mcrcsip.SharePoint
    • 刪除參考 Mcrcsip.Web
    • 打開添加引用對話框
    • 從瀏覽選項卡打開 Mcrcsip.Aws.Bol
    • 從瀏覽選項卡打開 Mcrcsip.Common
    • 從瀏覽選項卡打開 Mcrcsip.SharePoint
    • 從瀏覽選項卡打開 Mcrcsip.Web
  1. 建造

如果您在這一步仍然遇到錯誤,那麼您知道其中一項或全部

  • Mcrcsip.Aws.BOL
  • Mcrcsip.Common
  • Mcrcsip.SharePoint

共享您對 Mcrcsip.Web 的依賴,並引用舊版本。如果是這種情況,那麼對於上面列出的每個硬參考

  1. 選擇參考
  2. 按 F4
  3. 從 Path 屬性複制內容
  4. 打開文件對話框ildasm
  5. 粘貼到文件名
  6. 檢查清單

確保對上述三個硬引用中的每一個都執行此操作。一旦您確定這三個子集的哪個子集引用了舊版本的 Mcrcsip.Web,您現在可能會找到該項目,更新硬引用,重新建構它,然後最後更新您的硬引用,重新建構,瞧。鮑勃是你的叔叔。

呸。

結束

PS 為冗長而道歉。這不是一個非常複雜的問題,但我相信你會同意,它涉及很多細節。我真的希望這會有所幫助。也感謝您的合作:)

PPS 順便說一句,我從您的評論中推斷出原始開發人員在任何地方都使用了硬引用

$$ ie even within same solution $$. 也許他有他的理由,但在我看來,那是屁股。

引用自:https://stackoverflow.com/questions/2381931