Link SDK only + Entity Framework = System.ComponentModel build error - entity-framework

With linking set to SDK Only, I have an error on iOS like this:
MTOUCH : error MT2101: Can't resolve the reference 'System.Void
System.ComponentModel.DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider::.ctor(System.Type)',
referenced from the method
'System.ComponentModel.ICustomTypeDescriptor
System.Data.Entity.ModelConfiguration.Utilities.AttributeProvider::GetTypeDescriptor(System.Type)'
in 'System.ComponentModel.Annotations, Version=4.3.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
I use Entity Framework and a number of other 3rd party libraries that integrate with Entity Framework, and in the past I have needed to add a --linkskip argument for System.Core or a .Init call in my Appdelegate file for Sqlite, but these techniques havent helped me with this ComponentModel issue. I assume it's because of Entity Framework or one of the related 3rd party libraries I'm using since I know they use a lot of reflection. Has anyone run into this before?
EntityFrameworkCore.Triggers 1.2.2
LinqKit 1.1.17
Microsoft.Data.Sqlite.Core 3.1.6
Microsoft.EntityFrameworkCore 3.1.2
Microsoft.EntityFrameworkCore.Design 3.1.3
Microsoft.EntityFrameworkCore.Relational 3.1.2
Microsoft.EntityFrameworkCore.Sqlite 3.1.2
Microsoft.EntityFrameworkCore.Tools 3.1.3
Z.EntityFramework.Plus.EFCore 3.0.69
The projects using entity framework are class libraries that target .netstandard 2.0, and my main application uses xamarin forms 4.5 (have tried updating to 5.0 with no success)

I solved this problem manually referencing System.ComponentModel.Annotations.dll in .netstandard2.1 in nuget folder. You can try first to install the Annotations Nuget e if doesn't work you can try to manually reference.

Related

How does .NET resolve different versions of the same package?

This question pertains to .NET 5+, not .NET Framework.
Consider the following dependency tree:
MyWebsite has package references to RandomWebLibrary 1.0.0 and RandomJsonLibrary 2.0.0.
The NuGet package RandomWebLibrary 1.0.0 has a package reference to RandomJsonLibrary 1.0.0.
The NuGet package RandomJsonLibrary has no dependencies.
My questions:
What version(s) of RandomJsonLibrary will be loaded at runtime?
What happens if RandomJsonLibrary 2.0.0 has a completely different API than RandomJsonLibrary 1.0.0?
Can the author of MyWebsite do anything to fix problems that arise from having multiple versions of RandomJsonLibrary in the dependency tree? Is there an equivalent of .NET Framework's binding redirects in .NET 5+?
I'm asking out of curiosity, not because I am encountering a problem. For reference, here is the documentation on Understanding AssemblyLoadContext which seems relevant but did not answer my question.
These questions are answered by the documentation page How NuGet resolves package dependencies. The "Dependency resolution with PackageReference" section is what's relevant to this question since we are talking .NET 5+.
When the package graph for an application contains different versions of the same package, NuGet chooses the package that's closest to the application in the graph and ignores all others. This behavior allows an application to override any particular package version in the dependency graph.
In the example below, the application depends directly on Package B with a version constraint of >=2.0. The application also depends on Package A which in turn also depends on Package B, but with a >=1.0 constraint. Because the dependency on Package B 2.0 is nearer to the application in the graph, that version is used:
To answer the original questions:
RandomJsonLibrary 2.0.0 will be loaded at runtime.
I believe RandomWebLibrary will throw exceptions at runtime if RandomJsonLibrary 1.0.0 and 2.0.0 have incompatible APIs.
The author of MyWebsite can choose the exact version of any dependent package by installing that package directly into MyWebsite. In the case of RandomJsonLibrary, the author of MyWebsite should probably downgrade to RandomJsonLibrary 1.0.0 to prevent RandomWebLibrary from breaking. AFAIK there are no binding redirects in .NET 5+.

Satisfying a framework's dependencies while within another project

I am working on an iOS framework. My development environment is an iOS application project with the framework project within it, the framework's product is then added to the "Embedded binaries" and "Linked Frameworks and Libraries" sections of the application.
The previous setup works fine, but this particular framework I'm working on requires one other framework to function. I have installed this framework via Carthage and added it to the base application's project ("Embedded binaries" and "Linked Frameworks and Libraries") and then also the framework's project "Linked Frameworks and Libraries".
However when I run the application I get the following two errors (FrameworkOne is the framework I'm working on in a project, FrameworkTwo is the dependency):
dyld: lazy symbol binding failed: Symbol not found:
[symbol here]
Referenced from:
[path to iOS sim]/FrameworkOne.framework/FrameworkOne
Expected in:
[path to application]/Frameworks/FrameworkTwo.framework/FrameworkTwo
...and...
dyld: Symbol not found:
[symbol here]
...the same paths as above...
What am I doing wrong here?
The answer is simple and frustrating in hindsight: the version of the framework used within my application project and my framework project didn't match.
If you're having similar issues check that your application and framework are using the same version!

EF Core Driver cannot load netstandard or one of its dependencies in LinqPad 5

I created a .NET Full Framework class library using EF Core v 2.2.1 and downloaded the EF Core driver v 2.x for Linqpad 5 (5.36.03), and when I try to create a new connection to the class library DLL, I get the following error message:
Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependenceis. The system cannot find the file specified.
I have clicked the 'Restore nuGet Dependencies' and it gives me the message 'No NuGet dependencies detected'.
Any thoughts?
Did exactly what #magicandre1981 suggested and targted 4.7.2 for my class library. That fixed it!

Force NuGet to reference a .net framework 4.0 assembly in a 4.5 project?

I have two projects in my solution--one targets .net 4.0, the other targets .net 4.5. They both reference the same NuGet package which contains both 4.0 and 4.5 binaries.
How can I get NuGet to reference the same version--4.0--in both projects?
You can exclude the folder of the framework that you don't want to use (ExcludeAssets), and edit the PackageTargetFallback in your project.
In your project's csproj file:
<PackageTargetFallback Condition="'$(TargetFramework)'=='net45'">
$(PackageTargetFallback);net40
</PackageTargetFallback >
When referencing the package:
<PackageReference Include={package-ID} Version={version} ExcludeAssets="lib/$(TargetFramework)"/>
This way the package won't bring the binaries that you don't want, and the ones you want will be compatible.
Note: Taking dlls with a different target framework is not recommended.

Preventing automatic framework targeting of portable class libraries

I have a library published on nuget that is targeting .NET Framework 4.5
The solution looks like:
Solution
└─ Project.Net45
The nuget package looks like:
─lib
└─net45
I wanted to add a portable class library, so I modifed the solution to:
Solution
└─ Project.Net45
└─ Project.Pcl (Targets Windows Store Apps and Windows Phone 8)
I had to modify the code in the portable class library to work around things that were not compatible with those targets such as the serializable attribute and Thread.Sleep.
The problem is that the portable class library is automatically set to target .NET Framework 4.5 with the following message:
"The following frameworks will be selected automatically because they
support all of the available functionality that is portable between
the other frameworks you have selected: .NET Framework 4.5 and
higher".
and the nuget package now looks like:
─lib
└─net45
└─portable-net45+wp80+win
If I install this nuget package into a library targeting .NET Framework 4.5, I would rather the net45 library be used rather than the portable class library as the net45 library is smaller and doesn't have all the extra code needed to work around the missing features in windows phone 8 etc).
Will changing the nuget package to structure below have the desired effect :
─lib
└─net45
└─portable-wp80+win
Or am I misunderstanding the usage of portable class libraries?
NuGet looks for the best match when adding references to assemblies in the NuGet package.
If your project targets .NET 4.5 then NuGet will install the net45 assembly since it considers that the best match.
The PCL assembly will be used when your NuGet package is added to a PCL project that is compatible.
If you only had the PCL assembly in your NuGet package then NuGet would add a reference to it if you installed it into a project that targets .NET 4.5. However since you have both it will pick the net45 assembly.