Reputation: 781
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?
Upvotes: 1
Views: 1157
Reputation: 781
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.
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)
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
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.
어셈블리를 캐시에 추가했습니다.
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
(Oh! It runs well!)
PS C:\temp\MyNugetTest> .\MyNugetTest\bin\Debug\MyNugetTest.exe
objStr : {"hello":"world","main":"function"}
c1.ObjStr : {"hello":"world"}
(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
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)
Upvotes: 3
Reputation: 3691
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.
Upvotes: 2