Build failures in Visual Studio 15.6.3? ReSharper Ultimate 2017.3.5 to the rescue!
Have you been experiencing build failures in your multi-targeted project after installing Visual Studio 15.6.3 with
.NET Core SDK 2.1.102 (related YouTrack ticket and dotnet issue on GitHub)? The last few days we have worked tirelessly, burning all the midnight oil, to be able to bring you something to end your problems. It’s ReSharper Ultimate 2017.3.5 to the rescue!
Let’s now look under the hood to figure out why this issue has happened.
The bug is reproduced when Visual Studio and .NET Core SDK uses different versions of NuGet SDK.
Visual Studio 15.6.3 uses NuGet SDK 4.6.1; it ships .NET Core SDK 2.1.102 which uses NuGet SDK 4.6 (“broken” configuration)
Visual Studio 15.6.4 uses NuGet SDK 4.6.1; it ships .NET Core SDK 2.1.103 which uses NuGet SDK 4.6.1 (everything is OK)
Thus, if you use Visual Studio 15.6.3 + .NET Core SDK 2.1.102 + (ReSharper Ultimate 2017.3.3 or ReSharper Ultimate 2018.1 EAP3), you have the described bug. To solve the problem, you have to update ReSharper Ultimate to 2017.3.5 (this patch will also be available in the upcoming 2018.1 EAP4 soon).
You can also update Visual Studio to 15.6.4. The installer will upgrade .NET Core SDK to 2.1.103, and the problem will also be solved because you will get consistent versions of the NuGet SDK between Visual Studio and .NET Core SDK.
However, it’s still recommended to update ReSharper Ultimate because it fixes the bug in all possible configurations (the bug can be reproduced even with Visual Studio 15.6.4 in case of the custom .NET Core SDK version; e.g., it can be changed via global.json).
More technical details
Visual Studio, .NET Core SDK, and ReSharper share the same process. Each product has a NuGet SDK dependency, and each product has its own version of the NuGet SDK. Visual Studio and .NET Core SDK can’t share the same version of this dependency because Visual Studio should support different versions of .NET Core SDK. ReSharper 2017.3.x supports different versions of Visual Studio (from Visual Studio 2010) and different versions of .NET Core SDK. So, we ship own version of NuGet SDK because ReSharper can’t use the NuGet SDK from Visual Studio or .NET Core SDK. ReSharper uses NuGet 4.5 (NuGet 4.6+ requires .NET Framework 4.6 but ReSharper 2017.3/2018.1 should support .NET Framework 4.5, so it can’t use the latest version of NuGet SDK; this problem is going to be solved in ReSharper 2018.2). Thus, you could have up to 3 different versions of NuGet SDK in the same process:
All possible conflicts should be solved with the help of AssemblyResolvers which exist in all the products. These resolvers have the following order: Visual Studio, ReSharper, .NET Core SDK.
AssemblyResolver in ReSharper has tricky logic because of the plugins: new versions of ReSharper should support old versions of its plugins and old versions of ReSharper should support new versions of its plugins (in some cases there are no breaking changes in the public API). Sometimes it ignores the version requirement, and it might load an assembly with a version which is different from the required version.
When Visual Studio and .NET Core SDK use the same version of NuGet SDK, there are no problems: Visual Studio correctly resolves NuGet dependency and .NET Core SDK can use it without additional AssemblyResolver calls.
In case Visual Studio and .NET Core SDK use different versions of NuGet SDK, it has to also load NuGet SDK for .NET Core SDK. Unfortunately, the AssemblyResolver in ReSharper has a higher priority, so it tries to resolve the dependency before .NET Core SDK. And it resolves the dependency to its own NuGet SDK (because of the “light” requirements for the dependency versions) which differs from the required one. As a result, it has a version mismatch: .NET Core SDK can’t use the wrong version of NuGet SDK and fails to perform typical operations like restore or build.
Come and grab your copy of ReSharper Ultimate 2017.3.5.
PS: As you might have probably noticed, there is no mention of ReSharper Ultimate 2017.3.4, which is normally what you might expect to come after the 2017.3.3 build. It has been omitted for some technical reasons.