Best strategy to target .NET 4 from a NuGet package with a portable class library - nuget

I have a NuGet package for a library that is currently implemented only for .NET 4. But I have ported library code to support various platforms (WinRT, SL5, WP8) so ideally I would like to package it as a portable class library (PCL) to simplify the maintenance. But the library is using LINQ to XML (XELements etc.) that requires targeting .NET 4.0.3 and installting .NET 4.0.3 on a client machine.
So I have a dilemma regarding how to target plain .NET 4. If it was not about NuGet packages and I had a control of the user base I could simply state as a prerequisite installing .NET 4.0.3 runtime. However, I don't want to limit the user base in any way, so it looks like I will have to have two versions of the library: portable that targets .NET 4.5, SL5 and WP8 and non-portable targeting just .NET4. What's silly is that both libraries will have exactly the same code since LINQ to XML is of course supported in .NET 4, it's just PCLs that don't have such support when targeting .NET 4.
My first question is whether this seems to be a right strategy? The alternative would be to take away all XElement-dependent code from PCL and have it in non-portable parts, but this does not seem right because the code will be exactly the same for all libraries.
The second question is whether it makes sense to target .NET 4.0.3 from a PCL at all: if I have separate version targeting .NET 4 will users that have .NET 4.0.3 runtime installed gain anything from getting a PCL rather than plain .NET 4 version? I know .NET 4.0.3 has other improvements but those don't affect my library.

Yes, I think the best thing is to create two versions of your library, one targeting .NET 4 and another portable library that targets the other platforms you support. Use source file linking so you don't have to have two different copies of your source code, just two different Visual Studio projects.
You only need one NuGet package though. Put the .NET 4 version in lib/net40 and the portable version in lib/portable-net403+win8+wp8+sl5 (or whatever combination of platforms you decide to support). Then NuGet will install the right one depending on what a project is targeting. NuGet 2.1 or higher is required for this to work for the portable version.
In reference to the question about .NET 4.0.3, it's about giving the consumers of your library flexibility. The people using your library are using it to create applications. Supporting .NET 4 may not be as important to them as it is to you. By supporting .NET 4.0.3 in the portable version of your library, it means that if they choose to require .NET 4.0.3 in their apps, then they will be able to use your library from their own portable libraries and more easily share their app code across platforms.

Related

Why does NuGet package reference incorrect .NET framework/standard?

tl;dr:
I have a .NET Framework 4.7.2 project consuming a NuGet package which supports .NET Standard 2.0. That package, in turn, requires another package which supports .NET Standard 2.0. However, when run, the latter package uses net461 binaries rather than netstandard2.0.
How do I force a NuGet package & its dependencies to use .NET Standard 2.0?
Are there special steps required to consume a .NET Standard package from a .NET Framework 4.7.2 project?
Specifics:
I am trying to get the NuGet package for SparkplugNet (which uses the MQTTNet package) working in a .NET Framework 4.7.2 project - just the basic "How to use" SparkplugB example. Both projects support .NET Standard 2.0. After some debugging (details below), it appears MQTTNet is trying to use code paths specific to .NET Framework 4.6.1, rather than .NET Standard 2.0, and crashing with no feedback whatsoever.
To troubleshoot, I built SparkplugNet and MQTTNet from source. As far as I can tell, the crash comes from hitting .NET 4.5/4.6.1-specific code in CrossPlatformSocket.ConnectAsync(), specifically this line (in context):
await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, host, port, null).ConfigureAwait(false)
When I debug, _socket is a System.Net.Sockets.Socket which doesn't appears to have a BeginConnect() method, at least in the source file my debugger pulled. I am not sure why it branches to that code when .NET Standard 2.0 would be a better fit.
Back to a 4.7.2 project consuming SparkplugNet & MQTTNet via NuGet package.... If I look at the reference paths, SparkplugNet is properly pointed at the netstandard2.0 folder, but MQTTNet points to packages\MQTTnet.4.1.3.436\lib\net461\MQTTnet.dll. If I change the hint path manually in the project file, MSBuild appears to pull from the netstandard2.0 folder, but it still crashes. I assume it is the same cause, though I'm having trouble debugging using NuGet packages. Also, I'm hoping for a better solution than hacking hint paths.

How to get a .NET core 3.1 Project work with .NET 5.0 project

When .NET 5.0 was released, one of the features mentioned was the ability to create a .NET 5.0 component, that it would work with .NET 3.1, so you wouldn't have to use .net standard between different versions.
Well, I tried to use .net 3.1 with .net 5.0 and I keep getting errors. Is there something special we have to do to make these work? We have multiple applications at my company that use various versions of .NET core. from 2.2, 3.0, 3.1 to .net 5.0. We would like to create some NuGet packages for some of the reusable components, but trying to figure out how to use .net core through out these applications, I don't want to create them with .net standard.
Has anyone run into this or not?
You did not provide the errors, but despite that, it can already be said that .NET 5 does not ensure backwards compatibility. Microsoft provides information on compatibility and breaking changes here.
.NET 5 merges together .NET Framework and .NET Core, ending the burden of keeping both; the aim is to also include Mono and Xamarin (MAUI). However, it does not ensure compatibility with previous versions. This is a good article on the subject - some features were delayed to .NET 6 though.
Hence, the best ways for you to have the compatibility you want would be to use .NET Standard or, even better, migrate the applications to .NET 5, since previous versions' support will end soon. In the team I work, we made some migrations from .NET Core 3.x to .NET 5 and it was pretty straightforward.
It is worth noticing that .NET 5 is not LTS. .NET 6, on the other hand, is. More details on .NET releases and support policies here.
A .net 5.0 library/dll cannot be referenced from a .net version less than .net 5.0. .net standard 2.1 should be used for compatibility between the different versions of .net core and .net 5.0.
On another note - its probably best to update all .net core projects to 5.0 assuming this is possible. The End of Life has been reached on .net core versions <= 3.0 (not .net standard).
see here.

How to create a .Net NuGet package addressing 2.0 and 2.1

Our company has multiple applications that are .Net Framework 4.8 and we also are growing the number of applications that are .Net Core 3.1.
We have written a whole library of NuGet packages (in a private repository) written in .Net STANDARD 2.0 that are currently consumed by both the 4.8 and Core 3.1 applications mentioned above.
Standard 2.1 offers many new language features, such as Nullables, and we want to start to migrating our NuGet packages over to Standard 2.1, but obviously need to continue to support those applications still on .Net 4.8 (which can't consume Standard 2.1).
Obviously we need to branch our source code, but what is the convention for publishing two almost identical NuGet packages, one written in 2.0 and the other 2.1?
NuGet supports multiple-target-frameworks for a package. Please refer to doc to learn more.

how to install Microsoft.Azure.DocumentDB.Core on portable library

I get error installing documentDB nuget package.
Could not install package 'Microsoft.Azure.DocumentDB.Core 1.2.1'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.5,Profile=Profile7', but the package does not contain any assembly references or content files that are compatible with that framework.
Any ideas? thanks in advance.
The Core package actually targets NetStandard 1.6, not .Net Core specifically.
NetStandard is a library that acts as API for different runtimes and it's much more powerfull than PCL because it's platform-agnostic:
This means that the DocumentDb.Core package can run on .Net Core 1.0, .Net Framework, Xamarin and UWP.
If you are creating a PCL, I would recommend you to create a NetStandard library instead.
It will let your library support a much wider universe of platforms and the great thing is that, if a new platform comes along that supports NetStandard 1.6 (for example), your library will work without needing to recompile or republish it.
This error message tells us that this assembly Microsoft.Azure.DocumentDB.Core is not supported on portable library. From this assembly nuget site, we know that This client library enables client applications targeting .NET Core to connect to the Azure DocumentDB service. If you want to use Azure DocumentDB library, please try to see if this assembly works Install-Package Microsoft.Azure.DocumentDB

nuget - Reference specific framework version from installed package?

This scenario goes a bit against the whole way nuget works so what i might be asking for is a hack...
My problem:
I need to have Restsharp and Protobuf-net referred to in a .net assembly that going into SQL-CLR for Server 2008 (so max .net 3.5, framework 2.0).
Restsharp goes back to 3.5 as the lowest supported fwk version.
Protobuf-net 3.5 onwards has a lot of gunk referring to system.servicemodel (and WCF) which i don't need and use and actively want to remove because it causes issues with installing on SQL-CLR. Protobuf-net 2.0 doesn't have this :)
So i've built and tested my code with an assembly targeting .net 3.5 and i installed the restsharp nuget - which gave me the correct reference and i manually added a reference to the protobuf-net 2.0 distro.
This is where i'd like to know - can i (in any way) install the protobuf-net nuget package but still have it reference the .net20 DLL in my assembly which targets 3.5?
The static reference is not a huge deal since protobuf-net has been pretty stable, but i'd like to get the whole setup via nuget if possible.
In the end, this is a workaround as solution to:
protobuf-net version without system.servicemodel dependency?
If there's a better answer to that, i'd be very grateful :)
As far as I know, that is not possible. You could of course create your own custom build and host it on a local nuget drop, or as your own nuget package on the public feed. AFAIK, there's no way to do what you want inside a new nuget folder in the existing package.