c# - 使用nuget时,我该如何解决dll hell?

标签 c# .net dll dependencies nuget

在C#项目中使用nuget时,出现dll hell问题。 例如,如果您看到类似下图的内容,

- 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 工具自动修复它?

最佳答案

正如@Emrah Süngü 的回答,

作为各种测试的结果,为了解决dll hell问题,将GAC所需的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 packages目录下所有需要部署的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)

关于c# - 使用nuget时,我该如何解决dll hell?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44622743/

相关文章:

winapi - VS 2012 命名修改仍然适用于 dll 导出

c# - 根据条件降序排列

c# - 将 Dictionary<string, object> 转换为具有键的对象集合

c# - jqModal 取消从 Iframe 打开但显示在父窗口中的警报框

c# - TDD - 我做得对吗?

dll - Office 64 位中的 32 位 dll

c# - WCF REST - "Get"使用复杂类型

.net - 如何将介绍的 ML.Net 演示翻译成 F#?

c# - 跨多层次关系的 Entity Framework 查询

c# - 为什么我无法在 C# 中使用 P/Invoke 调用 C DLL 中的函数?