Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transitive runtime dependencies are discarded when packing project, causing runtime failure

Project A (.NET Standard 2.0) has a method that uses TestServer, so it has a reference to Microsoft.AspNetCore.TestHost. It is built into a NuGet package.

Project B (.NET Standard 2.0) has a reference to the NuGet package from A. It is also built into a NuGet package.

Project C (.NET Core 2.2) is an XUnit test project, that has a reference to NuGet package B. It has a single test that calls the method from A.

All these projects compile successfully. But when the test from C is run, it fails with the following:

System.IO.FileNotFoundException : Could not load file or assembly
'Microsoft.AspNetCore.TestHost, Version=2.2.0.0, Culture=neutral,
PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.

If I manually add a reference to Microsoft.AspNetCore.TestHost to C, the test executes successfully. But from my understanding of .NET and how it handles transitive dependencies, this shouldn't be necessary.

Am I wrong, or is something broken here?

like image 874
Ian Kemp Avatar asked Sep 02 '19 10:09

Ian Kemp


1 Answers

I figured out the problem, thanks to the assistance of @Darjan Bogdan.

Originally, project A was a .NET Framework project with packages.config and project.nuspec files, built into a package by running nuget pack project.nuspec during our build pipeline.

I then "upgraded" project A to .NET Standard 2.0 ("upgraded" = recreated it from scratch) and deleted the now-unnecessary packages.config and project.nuspec files, and changed the pack command to use the project file instead: nuget pack project.csproj. Because it continued to build successfully, I assumed everything was fine.

But I didn't know one important thing: Microsoft's NuGet team updated their tool to support the new-format csproj files, yet didn't bother to support the PackageReference element. The net result is that nuget pack on a new-format project succeeds and produces a nupkg file, but that file has no dependencies listed, which is an absolutely terrible time-wasting user experience.

So I have now changed our build pipeline to use dotnet pack instead and the dependencies come through as expected, and everything Just Works.

like image 53
Ian Kemp Avatar answered Sep 22 '22 00:09

Ian Kemp