Two Nuget Packages references conflicting reactive libraries - c#

My problem is very similar to that mentioned in this post:
System.ObservableExtensions.Subscribe: ambiguous reference
I would like to use the "GraphQL for .NET" nuget package and the "Plugin.BluetoothLE" package.
"GraphQL for .NET" references System.Reactive.Core and "Plugin.BluetoothLE" references System.Reactive
As stated in the other post:
Upon further investigation I found that ObservableExtensions exists both System.Reactive.Core and System.Reactive.
How do I resolve this? "Plugin.BluetoothLE" has System.Reactive 4.0.0 and "GraphQL for .NET" has System.Reactive.Core 3.1.1.
Is there a way for me to upgrade System.Reactive.Core inside GraphQL?

I havent tried this below but you can see on their github it was described as breaking change and there is workaround. see the highlighted sentence below.
v4.0 changes
Due to the overwhelming pain that fixing #205 - Implement assembly version strategy caused, we have refactored the libraries into a single library System.Reactive. To prevent breaking existing code that references the v3 libraries, we have facades with TypeForwarders to the new assembly. If you have a reference to a binary built against v3.0, then use the new System.Reactive.Compatibility package.
Supported Platforms
Rx 4.1 supports the following platforms
.NET Framework 4.6+
.NET Standard 2.0+ (including .NET Core, Xamarin and others)
UWP
Notably, Windows 8, Windows Phone 8 and legacy PCL libraries are no longer supported.
v3.0 breaking changes
The NuGet packages have changed their package naming in the move from v2.x.x to v3.0.0
Rx-Main is now System.Reactive
Rx-Core is now System.Reactive.Core
Rx-Interfaces is now System.Reactive.Interfaces
Rx-Linq is now System.Reactive.Linq
Rx-PlatformServices is now System.Reactive.PlatformServices
Rx-Testing is now Microsoft.Reactive.Testing
This brings the NuGet package naming in line with NuGet guidelines and also the dominant namespace in each package. The strong name key has also changed, which is considered a breaking change. However, there are no expected API changes, therefore, once you make the NuGet change, no code changes should be necessary.

One of two ways
Try setting Nuget to get the minimum version to the lowest one listed by your packages.
Split out the operations into separate libraries and manage the differing package version specific to library.

Related

Nuget package version resolution with different versions

I'm using a Nuget package that itself references a previous version of System.Reactive (specifically 4.3.2). I am not the maintainer and cannot change that, but would still like to use the package. However, all the projects in my solution reference a newer version of System.Reactive (5.0.0), and I am currently not at liberty to change that. This leads to a versioning conflict.
Back in the day I would use binding redirects, but we've transitioned to .NET Core and PackageRefernces recently, and it's unclear to me how I resolve such version conflicts using PackageReferences.
Two closely (I would assume) related questions then:
Is it possible to resolve the above scenarion, and if so, how?
How would one resolve the reverse situation (newer version in external package, older version in my solution/projects)?
Fundamentally, because you're resolving against two different major versions, there's currently no pleasant way of resolving this.
The fact that System.Reactive went from 4.x to 5.x suggests there are breaking changes, assuming it's actually following SemVer. So it's entirely possible that the package you're depending on relies on something in System.Reactive that was removed in 5.0.
Unless you want to get into loading the assemblies yourself using AssemblyLoadContext as a sort of isolation level, you're basically out of luck. .NET simply doesn't handle this situation well at the moment.
I suggest you work out the least painful way of getting everything onto the same major version. This could mean:
Downgrading your System.Reactive dependency
Persuading the maintainer of the other package to upgrade their System.Reactive dependency (which will mean them creating a new major version as well...)
Forking the other package so that you can upgrade its System.Reactive dependency yourself
None of these is likely to be simple, unfortunately.
When using .NET Core, you should find binding redirects unnecessary in this case.
I'll refer you to https://learn.microsoft.com/en-us/nuget/concepts/dependency-resolution#dependency-resolution-with-packagereference
If you are getting a nuget failure, you likely need to add a direct PackageReference to the problematic library, in order to enforce "Nearest wins" behaviour. I'm assuming the structure is something like:
Project:
-> NugetPackage1
-> System.Reactive (=5.0.0)
-> NugetPackage2
-> System.Reactive (=4.3.2)
and the suggested change would be to make it into:
Project:
-> NugetPackage1
-> System.Reactive (=5.0.0)
-> NugetPackage2
-> System.Reactive (=4.3.2)
-> System.Reactive (5.0.0)
(Please note that this kind of failure only happens if the package requirements explicitly conflict - in this case both packages want a specific version, rather than simply a version greater than X.)
Note that if you wanted to make the direct PackageReference the lower of the two versions, that would work as well.
If the versioning conflict is a runtime exception, please post the exception.

How to figure out the information of dependency packages for missing frameworks

Today I was adding a NuGet package DocumentFormat.OpenXml into my C# project. My C# project is targeting.Net framework v4.5. In NuGet package manager it shows the information of dependencies of the NuGet package as shown below:
There is no information corresponding to .Net Framework v4.5. So, how do I interpret this information if my project is targeting .Net Framework v4.5. Is this information missing or there is any default assumption in such cases may be no dependencies. Can someone share some information in this regard
Note: This question might look like a non-programming question but I got stuck even before writing a single line of code so asking it in this forum.
.NET Frameworks are backwards compatible. Meaning if your project is targeting v4.5, you can consume packages with lower versions, such as v4.0, v3.5.
NuGet's specialty is compatibility checking (if packages are authored correctly ofc) :)
NuGet knows the available frameworks are v3.5, v4.0, v4.6 and netstandard1.3.
The "nearest" compatible framework with v4.5 is v4.0, so it'll pick the v4.0 assets when you install it.
So the answer, it has no dependencies in your case.
Please note that framework compatibility is not always apparent from just looking at the TFMs on nuget.org, there's different fallbacks that NuGet will attempt.
So really the best way to figure out what the dependencies are would be to install it in the project, since NuGet might need to resolve conflicts etc. if you have other dependencies.

The current status of System.Net.Http vs. Microsoft.Net.Http

I am confused with packaging of HttpClient. Earlier it was distributed as a part of Microsoft.Http.Net NuGet package while System.Net.Http was considered legacy. Looks like now it's the opposite: there is a fresh System.Net.Http package for all platforms and Microsoft.Net.Http has not been updated in a while and according to folks at Microsoft development team is going to be deprecated.
Questions then:
Can we replace dependencies on Microsoft.Net.Http NuGet package with (the newest) System.Net.Http?
Should legacy .NET 4.0 platform still use Microsoft.Net.Http?
What about non-Windows platforms (iOS, Android)? The new System.Net.Http supports them, but I remember with Microsoft.Net.Http I had to install additionally Microsoft.Bcl.Build and Microsoft.Bcl in order to get cross-platform stuff to work. System.Net.Http doesn't depend on them. Can Bcl packages be skipped?
System.Net.Http lacks some Http extension methods, like SupportsPreAuthenticate, and an attempt to call these method results in runtime errors (missing method). How should we deal with this?
This has been for a long time and continues to be confusing. I have seen such messaging myself but as of right now, it appears System.Net.Http is the correct choice, at least for .NET on the Windows platform and has no external dependencies.
For .NET Core, I have used Microsoft.Net.Http although it does require Microsoft.BCL. Unless you are experiencing problems, I suggest leaving legacy systems as-is, especially since these namespaces seem to be moving targets.
If that isn't confusing enough for you, the HttpClient Sample linked from System.Net.Http uses Windows.Web.Http! That implementation is for Windows Store apps.
Perhaps next year this will all change again.

Consuming packages from Xamarin projects

I'm trying to make Npgsql, the PostgreSQL provider for .NET, available for consumption by Xamarin users. I've explored various methods for doing this and seem to be blocked.
First, a Xamarin project can consume packages which target certain PCL profiles. The problem is that none of of these PCL profiles contain System.Data, which Npgsql requires, even though Xamarin itself allows you to use System.Data.
Second, Npgsql already supports the .NET Platform Standard (version 3), and the documentation on the standard contains the following sentence:
If a library targets .NET Platform Standard version 1.3, it can only run on .NET Framework 4.6 or later, .NET Core, Universal Windows Platform 10 (UWP), and Mono/Xamarin platforms.
However, trying to go down this path yielded several errors (this question is one of them). My guess is that the Xamarin tooling isn't yet fullynetstandard-aware.
Finally, it seems possible to import Npgsql as a shared project inside the user's solution, but this seems like a very hacky and wrong solution - it bypasses NuGet entirely.
Does anyone have any info on this?
That npgsql package seems to be depending on pre-release packages (RC - Release Candidate). Run the install with -pre option:
Install-Package npgsql -pre
This worked at least when installing to an iOS project. Not sure if it functions correctly as none of the dependencies are added to the References, only Npgsql.
I believe your speculation is correct of Xamarin tooling not being fully netstandard/PCL5 aware AFAIK(Your speculation is as good as mine). This is a huge effort by all parties involved to be unified. There have also been significant changes on the dotnet end that can alter this.
For your questions about System.Data:
System.Data is missing a bit of functionality: https://developer.xamarin.com/guides/ios/advanced_topics/system.data/#Missing_Functionality
System.Data is available via the Xamarin.iOS.dll assembly as it's not supported in PCLs.
https://developer.xamarin.com/guides/ios/under_the_hood/assemblies/
https://msdn.microsoft.com/en-us/library/system.data(v=vs.110).aspx (Notice no PCL items inside)
Finally, there should be a blog post next week about netstandard via https://blogs.msdn.microsoft.com/dotnet/2016/05/23/changes-to-project-json/
I would highly recommend that you join the .NET core slack channel to ask any questions you may have.
http://tattoocoder.com/aspnet-slack-sign-up/

Do I have to include all System.Collections.Immutable dependencies?

I just switched from (an older) Microsoft.Bcl.Immutable NuGet package to System.Collections.Immutable and was surprised to find all these new package dependencies in my project:
System.Collections
System.Diagnostics.Debug
System.Globalization
System.Linq
System.Resources.ResourceManager
System.Runtime
System.Runtime.Extensions
System.Threading
They are listed as dependencies of the NuGet package, so they have a right to be there, yet they are obviously also already installed on my PC and my target environment (Azure btw) as they come with the framework.
I already have a large number of packages in my project and would like to avoid the additional overhead caused by these 8 packages, if possible (and without shooting myself in the foot).
Is it safe to remove these dependencies?
Do I now have to use these packages throughout my project because they might differ from their installed versions and some portion of my project might now use the wrong ones? (due to some DLL linking madness?)
Edit: Just for completeness, as there was a comment before: The dependencies are actual packages (not namespaces) and have to be downloaded, I'm targeting and compiling with .NET 4.6, working in VS2015. It's entirely possible though that something is outdated and the packages do not have to be loaded normally?
You are just seeing a side-effect of the Nuget package having to keep a lot of people happy. The package supports an enormous number of targets, it is proliferating rapidly as of late. I see support for Xamarin for OSX and iOS, Windows Phone 8.0 and 8.1, Windows Store, CoreCLR (the open source project), .NET 4.5, MonoTouch for iOS and Android and .NETCore (Silverlight).
These dependent packages just contain reference assemblies, the kind that are normally installed in your c:\program files x86\reference assemblies directory. The Nuget package doesn't take the chance that such a reference assembly might be missing and includes the whole kit and kaboodle.
After it is all downloaded, the package installer runs and adds the references you actually need in your project. Easy to see what happened, just open the References node of your project. If your targeted the desktop version of .NET 4.5 and up, the grand total of added references is one, just System.Collections.Immutable. Yes, you can remove them.

Categories