Dependency resolution differences between .NET Core and Mono - project.assets.json apparently causing problems
See original GitHub issueDescription
The dependency resolution process in .NET Core appears to differ from what happens on Mono, which is causing problems with some packages (specifically in this case, the Suave.OAuth 0.9.0-pre2 package).
Repro steps
I don’t yet know if this is reproducible on Windows, but I can reproduce this on Linux by the following method:
- Clone the https://github.com/fable-compiler/fable-suave-scaffold repo into a folder called
withdotnet
. - While that clones, start a new Terminal tab or window. In the second tab, create an empty folder called
withmono
, a sister folder towithdotnet
. - In the
withmono
project, create a new Suave project from the Forge Suave template (I used Ionide in VS Code and chose “New Project” from the menu, then picked the Suave template). Project foldersrc
, project nameWithMono
. - While Forge is busy creating the
withmono
project, go to your first Terminal tab (in thewithdotnet
folder) and editpaket.dependencies
. Addnuget Suave.OAuth prerelease
to the dependencies. (Suave.OAuth first started supporting .NET Core in 0.9.0, which as of this writing is still a prelease version. If Suave.OAuth 0.9.0 is released by the time you repro this, you can skip theprerelease
part of that line.) - Also edit
withmono/src/Server/paket.references
and addSuave.OAuth
to the references file. - Make sure you have .NET Core 1.0.4 installed (for Ubuntu, it’s in the
dotnet-dev-1.0.4
package). - Still in
withdotnet
, runmono .paket/paket.exe install
to make sure the Suave.OAuth NuGet package dependencies are resolved and thepaket.lock
file is updated. (The./build.sh
script in the fable-suave-scaffold project just does arestore
, not aninstall
, so it will skip the Suave.OAuth package if you haven’t done aninstall
, and you won’t trigger this bug). - Still in
withdotnet
, run./build.sh
. This will take a while, so switch back to the other Terminal tab now. - In
withmono
, editpaket.dependencies
andsrc/WithMono/paket.references
to addnuget Suave.OAuth prerelease
andSuave.Oauth
respectively, just as you did in thewithdotnet
project. - In
withmono
, run.paket/paket.bootstrapper.exe
to get Paket, then run.paket/paket.exe install
to set up thepaket.lock
file. - In
withmono
, run./build.sh
. You should see it succeed. - Switch back to the
withdotnet
tab, which should have failed by now. Scroll up past the hundreds of “Error: ConnectFailure (Connection refused)” messages to find their cause: .NET Core is trying to load the Suave assembly version 2.0.0, but you have 2.1.1 (or later, depending on when you run this repro). See error message below:
Could not load file or assembly ‘Suave, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null’. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
The root cause of this appears to be in the src/Server/obj/project.assets.json
file, where Suave.OAuth is listed as having a dependency on Suave version 2.0.0. This comes from the Suave.OAuth.nuspec file, where the Suave dependency is indeed listed as being “2.0.0”. However, the .nuspec specification says that a notation of “1.0” is the equivalent of “<= 1.0”. But the behavior of project.assets.json
appears to be different: the fact that project.assets.json
lists Suave.OAuth as having a dependency on "Suave": "2.0.0"
is the only place I can find where this dependency could be coming from.
Expected behavior
The Suave dependency of “2.0.0” should be treated as in the .nuspec file, and a Suave version of 2.1.1 should satisfy the dependency.
Actual behavior
Under Mono (and I presume under .Net Framework as well), the expected behavior is what I get. But under .Net Core, I cannot get this to work.
Known workarounds
The only workaround I’ve found so far is to explicitly list Suave 2.0.0
in paket.dependencies
under .NET Core. This makes MSBuild happy, because the assembly that it’s loading matches the one referenced. But I’m not happy, because Suave 2.1 includes at least one very important security fix. I can use Suave 2.0.0 while developing, but I can’t deploy that version of Suave.
Another workaround that I tried, but that failed, was to edit the project.assets.json
file by hand and change the "Suave": "2.0.0"
line to "Suave": ">= 2.0.0"
. But this edit was overwritten by Paket when I re-ran ,/build.sh
, so that didn’t work.
This is probably ultimately caused by a bug in .NET Core, but I have no idea how to create a repro that they will accept.
Possibly-related issues: #2208, #2497, and maybe others. And this could also be a PEBKAC issue: I am still very confused by .NET Core and its build system. The reason I used the fable-suave-scaffold project in my repro above is because the only way I’ve (so far) succeeded in building anything under .NET Core was to clone fable-suave-scaffold and build it. So I don’t actually know how to create a smaller repro project that will demonstrate this problem.
Issue Analytics
- State:
- Created 6 years ago
- Comments:9 (9 by maintainers)
Top GitHub Comments
Hm, I cannot reproduce this with a C# console application without paket 😕
Leaving this open because we need to warn or more likely error out if we detect this situation