简体   繁体   中英

When using nuget, how can i solve dll hell?

When using nuget in a C # project, there is a dll hell problem. For example, if you see something like the picture below,

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

The results are as follows.

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 which is always built later, overwrites the Newtonsoft.Json.dll file, so the version is determined to v10.0.3.

If I manually change the file name to Newtonsoft.Json.v5.0.1.dll , this problem will be solved. Is there any way to fix it automatically with nuget or visual studio tools?

As @Emrah Süngü answers,

As a result of various tests, it seems to be a good idea to distribute the dlls required by the GAC globally in order to solve the dll hell problem. If I develop a local application, it is cumbersome because the GAC registration process is included in the installation program. Therefore, it is better to perform GAC installation only when problems occur, rather than preempting all dependencies with GAC installation.

Below is the result of running the application after registering this GAC.




Newtonsoft.json.dll is not existed in both the execution directory and GAC, and execution error occurs.

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)




Check all the dlls that need to be deployed in the nuget packages directory.

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




Install / register all dlls in the GAC

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.

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




Ensure that you are properly installed / registered with the 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




Make sure my application runs well again

(Oh! It runs well!)

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




Remove / unregister Newtonsoft.Json from GAC.

(This step is dangerous and you will not need it most of the time. But I'll add it for testing.)

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




It also fails when I run my application.

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)

You can have each project reference a specific version of the same dll. There are two ways I can think of:

1) Put both versions of the dll in the GAC. Then, when referencing set the Copy Local = false and Specific Version = true.

2) Use your config file and assembly binding directives .

However, One of the main reasons we have GAC is to solve this problem. So I would recommend taking advantage of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM