Adding EF Core to a NET Standard project introduces transitive dependency versions incompatible with NuGet packages in other projects
I have a solution with multiple .NET Standard 2.0 projects.
One Project A uses the Google.Protobuf (3.11.2)
NuGet package, that depends on
System.Memory (4.5.3)
System.Buffers (4.4.0)
System.Numerics.Vectors (4.4.0)
System.Runtime.CompilerServices.Unsafe (4.5.2)
A few other projects also depend on System.Memory
and all use the same dependency versions.
Another Project B uses Microsoft.EntityFrameworkCore (3.1.0)
NuGet package that depends on
System.Memory (4.5.3)
System.Buffers (4.5.0)
System.Numerics.Vectors (4.5.0)
System.Runtime.CompilerServices.Unsafe (4.7.0)
Even though the System.Memory
version is (4.5.3) in both cases, it depends on System.Buffers
, System.Numerics.Vectors
and System.Runtime.CompilerServices.Unsafe
and their versions differ.
When I run the application that uses these projects (a Microsoft Prism WPF .NET Framework 4.8 app that uses Unity IoC) UnityContainer throws the following exception:
System.IO.FileLoadException: 'Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.
After searching for a solution I added this to my NuGet.Config:
<config>
<add key="DependencyVersion" value="Highest" />
</config>
In both, %appdata%\Nuget
and in the root folder of the .sln
file.
I also deleted the %userprofile%\.nuget\packages
folder.
Then I removed the NuGet packages from the projects and added them back again, but their dependecies come with the same versions as before.
If I navigate to "Manage NuGet Packages for Solution..." in Visual Studio and choose "Consolidate" it just says "No packages found"
Click on “Manage NuGet Packages for Solution…” to open a slightly extended dialog to manage your NuGet packages: Browse, Installed and Updates work like the menus in the “default” NuGet packages dialog but contain all projects of this solution. The big addition is the Consolidate tab.
Click on one of them and on the right hand side you can choose the project that you want it to be installed. Show activity on this post. So if I copy and paste the packages. config file from my old project to new project.
What's a transitive NuGet dependency? Let's first start with a slightly simpler question: what is a transitive dependency? A transitive dependency is an indirect dependency; you depend on something which itself has another dependency that you don't depend on.
In this SDK-style format project references (represented by <ProjectReference> entry in . csproj file) are transitive. This is different to old non-SDK .
I managed to reproduce the problem.
I created two new .net standard 2.0 project
class libraries.
On the first I added EF Core
.
On the second I added Google protobuf
.
Both same versions as you mention.
For EF core I created a new class that just inherits from DbContext
.
For Protobuf I just created an empty class as I am not familiar on how to use it.
I was still able to replicate the problem though.
Then I created a console app .net framework 4.7.2
referencing the above two projects.
I instantiated the two classes in the Console App and got error System.IO.FileLoadException: 'Could not load file or assembly...
I went to all three projects and added this line to the csproj
.
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
to the Property Group.
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
After that I built and ran again and no error appeared.
Please let me know your results. Even if my solution does not work for you, I believe it is good practice to have it.
To quote Oren.
"Using .NET Standard requires you to use PackageReference to eliminate the pain of “lots of packages” as well as properly handle transitive dependencies. While you may be able to use .NET Standard without PackageReference, I wouldn’t recommend it."
Also Hanselman mentions: "The "full" Framework projects are using the older .csproj format and by default, they use package.config to manage dependencies. The newer projects can reference Packages as first-class references. So we need to tell ALL projects in this solution to manage and restore their packages as "PackageReferences.""
Here are my sources.
https://www.hanselman.com/blog/ReferencingNETStandardAssembliesFromBothNETCoreAndNETFramework.aspx
https://oren.codes/2017/04/23/using-xamarin-forms-with-net-standard-vs-2017-edition/
Updated according to Sommen's extra info from the github issues Kudos to Sommen for providing this extra info. Also Kudos to Immo Landwerth for providing this Info at GitHub. I will provide as is the Workarounds that already exist in the Github page just for complecity as advised by the OP jinjinov.
Taken from GitHub Issues
packages.config
but uses PackageReference
for NuGet packages:
packages.config
, simply add
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
.packages.config
, convert the contents to package references in the project file. The syntax is like this:
<PackageReference Include="package-id" Version="package-version" />
By default, binding redirects aren't added to class library projects. This is problematic for unit testing projects as they are essentially like apps. So in addition to what's outlined in automatic binding redirects you also need to specify GenerateBindingRedirectsOutputType
:
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
There is also a discussion section that provides more information -> GitHub discussion
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With