簡體   English   中英

使用nuget時,如何解決dll的問題?

[英]When using nuget, how can i solve dll hell?

在C#項目中使用nuget時,存在dll地獄問題。 例如,如果您看到類似下面的圖片,

- MyNugetTest
    - Newtonsoft.Json : v10.0.3
    - ...
    - MyLib
        - Newtonsoft.Json : v5.0.1
        - ...

結果如下。

PS C:\temp\MyNugetTest> ls .\MyNugetTest\bin\ -Recurse | select FullName
FullName
--------
C:\temp\MyNugetTest\MyNugetTest\bin\Debug
C:\temp\MyNugetTest\MyNugetTest\bin\Debug\MyLib.dll
C:\temp\MyNugetTest\MyNugetTest\bin\Debug\MyLib.pdb
C:\temp\MyNugetTest\MyNugetTest\bin\Debug\MyNugetTest.exe
C:\temp\MyNugetTest\MyNugetTest\bin\Debug\MyNugetTest.exe.config
C:\temp\MyNugetTest\MyNugetTest\bin\Debug\MyNugetTest.pdb
C:\temp\MyNugetTest\MyNugetTest\bin\Debug\Newtonsoft.Json.dll
C:\temp\MyNugetTest\MyNugetTest\bin\Debug\Newtonsoft.Json.xml

PS C:\temp\MyNugetTest> [System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\temp\MyNugetTest\MyNugetTest\bin\Debug\Newtonsoft.Json.dll").FileVersion
10.0.3.21018

以后始終會構建的MyNugetTest會覆蓋Newtonsoft.Json.dll文件,因此該版本確定為v10.0.3。

如果我手動將文件名更改為Newtonsoft.Json.v5.0.1.dll ,則將解決此問題。 有什么方法可以使用nuget或Visual Studio工具自動修復它嗎?

@EmrahSüngü回答時,

經過各種測試,將GAC所需的dll全局分發以解決dll地獄問題似乎是個好主意。 如果我開發本地應用程序,那么它將很麻煩,因為安裝程序中包含GAC注冊過程。 因此,最好僅在出現問題時才執行GAC安裝,而不是先占GAC安裝的所有依賴項。

以下是注冊此GAC后運行應用程序的結果。




在執行目錄和GAC中都不存在Newtonsoft.json.dll,並且發生執行錯誤。

PS C:\temp\MyNugetTest> .\MyNugetTest\bin\Debug\MyNugetTest.exe

처리되지 않은 예외: System.IO.FileNotFoundException: 파일이나 어셈블리 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' 또는 여기에 종속되어 있는 파일이나 어셈
블리 중 하나를 로드할 수 없습니다. 지정된 파일을 찾을 수 없습니다.
   위치: MyNugetTest.Program.Main(String[] args)




檢查nuget軟件包目錄中需要部署的所有dll。

PS C:\temp\MyNugetTest> ls .\packages\*.dll -Recurse | select FullName
FullName
--------
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\net20\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\net35\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\net40\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.0\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\portable-net40+sl5+win8+wp8+wpa81\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.10.0.3\lib\portable-net45+win8+wp8+wpa81\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\net20\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\net35\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\net40\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\net45\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\netcore45\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\portable-net40+sl4+wp7+win8\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\portable-net45+wp80+win8\Newtonsoft.Json.dll
C:\temp\MyNugetTest\packages\Newtonsoft.Json.5.0.1\lib\wp80\Newtonsoft.Json.dll




在GAC中安裝/注冊所有dll

PS C:\temp\MyNugetTest> ls .\packages\*.dll -Recurse | foreach { gacutil -i $_.FullName }
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

어셈블리를 캐시에 추가했습니다.




確保您已正確安裝/在GAC中注冊

PS C:\temp\MyNugetTest> ls C:\Windows\assembly\GAC_MSIL\Newtonsoft.Json\*.dll -Recurse | select FullName

FullName
--------
C:\Windows\assembly\GAC_MSIL\Newtonsoft.Json\10.0.0.0__30ad4fe6b2a6aeed\Newtonsoft.Json.dll
C:\Windows\assembly\GAC_MSIL\Newtonsoft.Json\4.5.0.0__30ad4fe6b2a6aeed\Newtonsoft.Json.dll




確保我的應用程序再次正常運行

(哦!運行良好!)

PS C:\temp\MyNugetTest> .\MyNugetTest\bin\Debug\MyNugetTest.exe
objStr : {"hello":"world","main":"function"}
c1.ObjStr : {"hello":"world"}




從GAC刪除/注銷Newtonsoft.Json。

(此步驟很危險,您通常不會用到。但是我將其添加進行測試。)

PS C:\temp\MyNugetTest> gacutil -u Newtonsoft.Json
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.


어셈블리: Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL
제거됨: Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL

어셈블리: Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL
제거됨: Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL
제거한 어셈블리 수 = 2
실패한 횟수 = 0




當我運行我的應用程序時,它也會失敗。

PS C:\temp\MyNugetTest> .\MyNugetTest\bin\Debug\MyNugetTest.exe

처리되지 않은 예외: System.IO.FileNotFoundException: 파일이나 어셈블리 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' 또는 여기에 종속되어 있는 파일이나 어셈
블리 중 하나를 로드할 수 없습니다. 지정된 파일을 찾을 수 없습니다.
   위치: MyNugetTest.Program.Main(String[] args)

您可以讓每個項目引用同一dll的特定版本。 我可以想到兩種方法:

1)將兩個版本的dll放入GAC。 然后,在引用時設置“復制本地” =“ false”和“特定版本” =“ true”。

2)使用您的配置文件和程序集綁定指令

但是,擁有GAC的主要原因之一就是要解決此問題。 因此,我建議您利用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM