TL;DR:
Given: I wrote a library with relatively portable functionality (for example, Left.Pad.©.dll). I want to make it available though NuGet.
Requirement: If somebody wants to use my library on any version of any platform on any version of any operating system with any updates installed by writing code in any IDE or any code editor, they should be able to do it.
Question: What is the minimum set of NuGet target frameworks to achieve that?
Bonus question: If there're any "dead" frameworks which shouldn't be targeted, or something else which should be taken into consideration when choosing target frameworks, you can mention it too.
Thoughts (old version):
NuGet packages support multiple .NET Framework versions and profiles, for example, a package can provide net20, net30, net35, net40, net45, sl3, sl4, sl5 etc. versions. However, assuming there aren't always differences in the functionality of a package, providing a lot of versions would be a waste of build time and package size and cause unnecessary complexity. On the other hand, providing a package just for the lowest supported Framework version could cause missing functionality, for example .NET 4 supports in-process side-by-side execution of multiple CLR versions, but previous versions don't, so this feature will be lost if just a version for .NET 3.5 is provided (I'm not sure; I've never used it and don't know the details). If a PCL version is provided, the logic is simple I assume: just exclude versions which PCL covers.
At the moment of writing, the easiest way is to create a .NET Standard 1.1 project. It supports
.NET Core 1.0 and higher
.NET Framework 4.5 and higher
Mono, Xamarin, Windows Phone and more...
So pretty much all of the modern platforms. If you want to support older platforms, ex. .NET Framework 3.0, add this as a separate "folder" in NuGet. This way, newer .NET Core applications can still use your package.
More information
.NET Standard acts a replacement for PCL. The lowest .NET Framework you can target with PCL is 4.0, which isn't much lower than 4.5 with .NET Standard 1.1 (thus won't make your package much more accessible).
PCL also doesn't seem to support .NET Core, while .NET Standard nearly supports all platforms:
Also note that according to Microsoft, only .NET Framework 3.5 SP1 and .NET Framework >= 4.5.2 are currently supported. All other .NET Framework versions already reached end of life and won't get any updates. Windows Phone is also dead and Silverlight isn't getting anywhere too.
As #Lex Li mentioned in the comments, .NET Standard 1.1 has a very low API surface, which means there are maybe some important APIs missing. Because of that, most NuGet packages use a higher .NET Standard version. It is recommended to use the lowest .NET Standard version possible.
So with .NET Standard 1.1, you will support a huge majority of the modern frameworks. Sadly, I couldn't find any .NET Framework distribution statistics...
If you really want to make your package available for every platform, take a look at the possible target platforms for NuGet. I think you need atleast net11 and netstandard1.0, maybe add some Silverlight and .NET MicroFramework support...
Solution of 2018
Based on given asnwers and assuming no dependency on platform-specific technologies (like System.Drawing, ASP.NET or WPF; in which case just target the platform you can and be done with it):
netstandard1.0—netstandard2.0 Start with .NET Standard 1.0 and go up until you reach maximum functionality.
This should cover:
.NET Framework 4.5
.NET Core 1.0
Mono 4.6
Xamarin.iOS 10.0
Xamarin.Android 7.0
Windows Universal 10.0
Windows non-Universal 8.0 (up to .NET Standard 1.2)
Windows Phone 8.1 (up to .NET Standard 1.2)
Windows Phone Silverlight 8.0 (up to .NET Standard 1.0)
If you can't reasonably implement the library within the limits of relatively small .NET Standard 1.0–1.2, the last three points are likely to be excluded. If you still need them, see points below.
.NET Standard 1.5+ increases the requirements on the versions of the frameworks and operating systems, so multi-targeting .NET Standard versions may be required for maximum compatibility.
portable-net40+* The next major point is obsolete PCL. Its .NET Framework 4.5+ versions aren't relevant as they're mostly covered by .NET Standard. If you want to support Windows Phone 8 and non-Universal Windows Store 8, you should do it through PCL, unless you're limited by API, in which case you'll have to add platform-specific targets.
If you don't need any of additional platforms and .NET Framework 4.0 provides some useful additional functionality over .NET 3.5, you can target it directly, not through PCL.
This should cover:
.NET Framework 4.0
Windows non-Universal 8.0
Windows Phone 8.0
Windows Phone Silverlight 8.0
net20—net35 If you want to support ancient desktop Windows versions (like Windows XP) and unupdated more recent Windows versions (like Windows Vista+ with .NET 3.0+), you should add support for desktop .NET Framework targets directly. Note that as of 2018-01-01, the lowest supported .NET is 3.5 SP1, so going lower than that is probably unnecessary and will likely limit API available to you too much with no real benefits.
This should cover:
.NET Framework 2.0-3.5
Windows XP
There're other platforms, namely Xamarin-specific ones, Tizen, .NET Micro etc. They can be accessed only by targeting them directly.
This should cover:
Everything else
TL;DR
Something like netstandard1.1+portable-net40+win8+net35 covers every relevant platform.
Solution of the future
When old .NET versions completely die, only .NET Standard should remain. Well, unless Microsoft invents yet another cross-platform unification technology, like it already did with .NET, .NET PCL, .NET Standard...
TL;DR
Use the lowest netstandard you can.
You should target .net framework 2.0 and above. The decision should be based on the platform the application will run in production.
.net 2.0 comes included in Windows 2008 server (SP2 and onward) and people still use it extensively in production.
Ref https://en.wikipedia.org/wiki/.NET_Framework
If you want it to be used not only on Windows - .NET Standard is the way to go. Target latest as question of what libraries to use comes early in a project and is rarely revisited and new projects tend to use recent versions of frameworks and libraries.
What .NET Standard versions are supported by what versions of other frameworks (GitHub).
What .NET Framework versions are supported by which Windows Server versions (MS Docs).
Server version share in SpiceWork network. It is not a representation of global data, but it's best data I found to get idea of Windows Server market share.
Info on Linux prerequisites for .NET Core versions (MS Docs).
You can find recent market shares of user devices based on internet usage easily.
See the numbers, pick platforms you want to reach and cross-reference it with which versions of .NET are available on them.
Targeting .Net Standard would give your nuget package the luxury of being employable in .NET framework ,.NET core, mono, Xamarin, Universal Windows Platform, and Windows Phone projects.
See the following taken from this answer
To decide which version of .Net standard you should target use the following table:
Source.
Looking at the above table I would recommend going with .Net standard 1.0 if you care about Windows Phone Silverlight or .Net standard 1.2 if you do not.
Also, as far as I noticed lots of people that chose .net core are actually using .net core 2.0 so you might want to create a seperate nuget version for them with .net standard 2.0.
About the second part of your question, even if a specific framework is dead that does not mean that it would go away instantly, it would be still used for several years before it is completely dead, simply moving to different options takes time.
Another thing that I would take into consideration is the common used libraries, like Masstransit, EPPlus, and the commonly used IOCs, etc.. I would take a general look on the frameworks supported by them and follow because many undergoing projects might be driven by such libraries.
Does anyone know if .NET Standard 2.0.0 is supported on Mono? I currently have a build that is working fine on windows 10. When I attempt to use in Mono in a Ubuntu Linux environment I get the following error:
Could not locate the assembly 'netstandard'. Check to make sure the assembly exists on disk.
Dotnet core 2 is added with no problems via the SDK, but I seem to not have any references to .NET Standard 2. I had a similar problem on windows 10 originally, which was resolved after I updated my version of visual studio.
Consult the release notes for details, but Mono 5.4.0 includes NuGet 4.3.0 and MSBuild 15.4.
Mono 4.8.0 Preliminary support
API additions for .NET Standard 2.0
We added APIs to comply with .NET Standard 2.0, which is still a work in progress at the time of this writing. Note that in some cases an implementation is still missing and will throw at runtime.
Mono 5.2.0 Runtime support (compiling is in "Preview Status")
.NET Standard 2.0 groundwork
We’ve done all the groundwork to support libraries that conform to .NET Standard 2.0. Loading and running a library compiled against the 2.0 standard should work fine, tooling support (i.e. creating a .NET Standard 2.0 library) is still in preview though.
.NET Core 2.0 SDK Installation needed
You’ll need to install the .NET Core 2.0 SDK for tooling support as we use the MSBuild tasks which are installed as part of the .NET Core 2.0 SDK, similar to how Visual Studio/MSBuild on Windows does it.
So I am trying to build a small interface for a side project. I have a private MongoDB instance and am trying to use UWP as my GUI. My goal was to use the MongoDB C# driver to provide the interface between my app and the server. The problem is the driver is only compatible with .NET Framework 4.5.2 or .NET standard 1.5.
I am having problems selecting a library type to use with my UWP app to interface the two. Any Ideas? If I have to I am even willing to spin off an additional library just to handle the interface of the driver and my model classes.
As you've known, MongoDB.Driver targets .NET Standard 1.5. However, for now, the highest version of .NET Standard that Universal Windows Platform supports is 1.4, which means this package is not compatible with UWP apps. So we can't use MongoDB C# Driver with a UWP app now. For more info, please see .NET Standard.
But a good news is that .NET Standard 2.0 has released and UWP will also support it in the upcoming version (expected to ship later this year). See Announcing .NET Standard 2.0. With .NET Standard 2.0, we should be able to MongoDB C# Driver in UWP apps. And if you want to do a test now, you can join Windows Insider Program and try with Visual Studio 2017 Version 15.4 Preview.
Visual Studio 2017 version 15.4 Preview brings first class support for developers targeting the Windows Fall Creators Update SDK preview. The Windows Fall Creators Update brings support for .NET Standard 2.0 to UWP development.
For more info, please see Visual Studio 2017 Version 15.4 Preview and UWP & .NET Standard 2.0: A preview is now available!
When you use a .net standard lib from the full .net framework you end up having to include/deploy .net standard versions of all the System.* assemblies the .net standard library uses.
Now that Xamarin supports .net standard and microsoft is recommending people use .net standard rather than PCL we will soon need to switch (library developers are abandoning PCL support).
My question is does using a .net standard library in a Xamarin for Android project mean that multiple system assemblies will be deployed (the .net standard version and the mono version)?
Xamarin apps are already much bigger than native and having to include duplicates of all the system assemblies we need could be a deal breaker going forward.
The .NET Standard(s) define the API surface of each version. The implementation of the API surface lies with the platform.
In the case of Xamarin the surface is implemented in the Mono framework which is deployed with every app. (And has been before)
If you reference nothing but the NETStandard Library the final .apk file will not increase.
Additional NuGet packages might bring in extra NetStandard specific dependencies (which could previously have been handled by the .net / mono framework itself)
I have PCL Library and I want to add it to standard (.net 4.6) C# console application. Everything is fine as long as I don't use any PCL specific classes inside the library. And if I do, I get an error "unsupported PCL profile". This error is not googlable. But the same library works fine in UWP application. I am searching for a solution or official explanation why I can't use PCL in non UWP application.
Yes you can. PCL is basically intersection of available API's across different platforms. The disadvantage is that the more target platforms you choose the smaller is the intersection:
Another disadvantage of PCL is that it generates separate assembly for each platform.
That's why Microsoft comes with .NET Standard - a replacement of PCL that uses different approach.
Think about .NET Standard as an interface, that defines set of API's. Then the platforms like .NET Framework, .NET Core, Xamarin.iOS, Xamarin.Android will implement the .NET Standard.
interface NetStandard1_0 {
}
interface NetStandard1_1 : NetStandard1_0{
}
interface NetStandard1_2 : NetStandard1_1{
}
net46: NetStandard1_6 {
}
dnxcode46: NetStandard1_6 {
}
As a result, you won't target specific platforms, but a version of .NET Standard instead. When your library targets .NET Standard, it can be used in any platform that implements the .NET Standards. Another advantage is you wont need separate assemblies for different platforms anymore. There will be single assembly that runs just everywhere.
However, I recommend you to wait until April 2017 when .NET Standrard 2.0 should be released. Microsoft promised that all platforms (.NET Framework, .NET Core, Xamarin.iOS, Xamarin.Android) will support this version of .NET Standard and it will have official support in Visual Studio. Also, Visual Studio projects using project.json will be converted to .csproj, so all Visual Studio projects will use the same format and it will solve a lot of compatibility issues. Cleanning of the mess that appeared in .NET last years was absolutelly necessary
Sure you can.
Just add .NET 4.6 to selected platforms:
It's appears at time when you create PCL.
More information here:
Cross-Platform Development with the Portable Class Library
Or you can change platforms in existing PCL. Just go to properties page and you will see:
Here is a good blog post about how to call UWP API from desktop App:
How to call UWP APIs from a desktop VB/C# app