19

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.

Athari
  • 33,702
  • 16
  • 105
  • 146
  • 3
    Just use the lowest version that *you* need. Works on any equal or higher version. – Hans Passant Oct 16 '15 at 18:58
  • .NET Core is a *framework *(like Xamarin and .NET Framework), Standard is a "contract/api", and PCL is outdated.This page is a good starting point : https://learn.microsoft.com/en-us/dotnet/standard/net-standard and it shows there's no generic answer to such a generic question. It's not obious what you're after, maybe you should rephrase the question entirely IMHO. – Simon Mourier Jan 08 '18 at 06:39
  • @SimonMourier NuGet calls them all "[frameworks](https://learn.microsoft.com/en-us/nuget/schema/target-frameworks#supported-frameworks)". Anyway, edited the question to hopefully make it more clear. – Athari Jan 08 '18 at 08:44
  • 1
    It is meaningless to keep this question open for such a long time, as the answer will shift based on the product lifecycle. – Lex Li Jan 08 '18 at 20:40
  • As lex li says, the question has no real answer. Today, for a new project, I would use netstandard 2.0, as advertised by Microsoft. There is no simple solution to support "any", "everything", like you want and I think it's pointless (SL and WP are dead, PCL is obsolete, etc.) – Simon Mourier Jan 10 '18 at 08:42
  • @SimonMourier The answer to my question is indeed a moving target, yet the problem exists, it needs to be solved and it isn't trivial as so many factors need to be taken into account (compatibility graph is crazy). When answers get outdated, I can just start another bounty. However, I hope .NET Standard remains the easiest answer in the foreseeable future and no more "portability technologies" are invented. – Athari Jan 10 '18 at 10:41

5 Answers5

12

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: Table of .NET Standard support

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...

Manuel Allenspach
  • 12,467
  • 14
  • 54
  • 76
  • 1
    Silverlight, though lifecycle ending in 2022, is almost dead with no main stream browsers support it at all. You probably should also point out that the API surface of .NET Standard 1.1 is pretty small, and most of famous .NET open source libraries on NuGet are either targeting 1.3 or 2.0. – Lex Li Jan 08 '18 at 20:46
  • I'm confused by the last 3 rows in this table. How does Windows version limit compatibility with .NET Standard exactly? / Those interested in servers are on the newest .NET Core I guess, and SL is officially dead, so these parts of PCL are irrelevant. The only somewhat relevant part left is probably older Win8 Universal apps (ugh, this mess of "universal" platforms). One major feature of .NET 4.0- is that it's available on Windows XP, which is kinda dead, but not completely so in Enterprise. – Athari Jan 09 '18 at 04:57
  • Overall, if I decide to go down from `netstandard1.1`, looks like I'll target `net40`/`portable-net40+win8`, and even lower just `net35`. So, the point of max compatibility with at least remotely relevant platforms seems to be `netstandard1.1`+`portable-net40+win8`+`net35`. – Athari Jan 09 '18 at 04:57
  • @LexLi If I switch to `netstandard1.3` or `netstandard2.0` from `netstandard1.1`, compatibility with what things do I miss? 1.3 seems to require the increased version of the main .NET Framework (4.5 vs 4.6) and drop support for WP, 2.0 seems to require updates to OS as well. Is that correct? I'm confised by the last 3 rows in the compatibility table. – Athari Jan 09 '18 at 05:01
  • @Athari The "Windows" row seems to mean Windows Store Apps that came with windows 8. .NET Core versions aren't tied to an OS version, see the [supported .NET Core 2 operating systems](https://github.com/dotnet/core/blob/master/release-notes/2.0/2.0-supported-os.md). You only lose Windows Store/Windows Phone support if you use `netstandard1.3`+`portable-net40+win8`+`net35` instead of `netstandard1.1`+`...`, since `net35` covers the other .NET Framework versions. – Manuel Allenspach Jan 09 '18 at 07:17
  • I wonder if this is still the best advice. Microsoft has come out with a lot of new features and fixes that will only be available on .NET Core. – Jonathan Wood Mar 09 '20 at 19:26
5

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):

  1. netstandard1.0netstandard2.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.

  2. 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
  3. net20net35 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
  4. 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.

Athari
  • 33,702
  • 16
  • 105
  • 146
2

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

Vikram Kumar
  • 3,876
  • 1
  • 17
  • 28
  • I have asked a [related/kind-of follow-up question](http://stackoverflow.com/questions/37906127/do-all-intermediate-versions-have-to-be-specified-in-nuget-packages) about *how* to target ".NET Framework # and above". – O. R. Mapper Jun 19 '16 at 10:21
1

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.

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.

Athari
  • 33,702
  • 16
  • 105
  • 146
Justinas Marozas
  • 2,482
  • 1
  • 17
  • 37
0

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

.Net standard

To decide which version of .Net standard you should target use the following table:

.net standard support 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.

Yahya Hussein
  • 8,767
  • 15
  • 58
  • 114