Skip to content

Instantly share code, notes, and snippets.

@davidfowl
Last active February 10, 2024 22:22
Star You must be signed in to star a gist
Save davidfowl/8939f305567e1755412d6dc0b8baf1b7 to your computer and use it in GitHub Desktop.
How .NET Standard relates to .NET Platforms
using System;
namespace Analogy
{
// Each interface represents a target framework and methods represents groups of APIs available on that target framework.
// The goal is to show the relationship between .NET Standard API surface and other .NET platforms
// .NET Standard
interface INetStandard10
{
void Primitives();
void Reflection();
void Tasks();
void Collections();
void Linq();
}
interface INetStandard11 : INetStandard10
{
void ConcurrentCollections();
void InteropServices();
}
interface INetStandard12 : INetStandard11
{
void ThreadingTimer();
}
interface INetStandard13 : INetStandard12
{
void FileSystem();
void Console();
void ThreadPool();
void Process();
void Sockets();
void AsyncLocal();
}
interface INetStandard14 : INetStandard13
{
void IsolatedStorage();
}
interface INetStandard15 : INetStandard14
{
void AssemblyLoadContext();
}
// .NET Framework
interface INetFramework45 : INetStandard11
{
void FileSystem();
void Console();
void ThreadPool();
void Crypto();
void WebSockets();
void Process();
void Sockets();
void AppDomain();
void Xml();
void Drawing();
void SystemWeb();
void WPF();
void WindowsForms();
void WCF();
}
interface INetFramework451 : INetFramework45, INetStandard12
{
// TODO: .NET Framework 4.5.1 specific APIs
}
interface INetFramework452 : INetFramework451, INetStandard12
{
// TODO: .NET Framework 4.5.2 specific APIs
}
interface INetFramework46 : INetFramework452, INetStandard13
{
// TODO: .NET Framework 4.6 specific APIs
}
interface INetFramework461 : INetFramework46, INetStandard14
{
// TODO: .NET Framework 4.6.1 specific APIs
}
interface INetFramework462 : INetFramework461, INetStandard15
{
// TODO: .NET Framework 4.6 specific APIs
}
// Mono
interface IMono43 : INetFramework46
{
void MonoSpecificApi();
}
// Windows Universal Platform
interface IWindowsUniversalPlatform : INetStandard14
{
void GPS();
void Xaml();
}
// Xamarin
interface IXamarinIOS : INetStandard15
{
void AppleAPIs();
}
interface IXamarinAndroid : INetStandard15
{
void GoogleAPIs();
}
// .NET Core
interface INetCoreApp10 : INetStandard15
{
}
// Future platform
interface ISomeFuturePlatform : INetStandard13
{
// A future platform chooses to implement a specific .NET Standard version.
// All libraries that target that version are instantly compatible with this new
// platform
}
}
namespace Analogy
{
/// <summary>
/// This example shows that a library that needs access to target .NET Standard 1.3
/// can only access APIs available in that .NET Standard. Even though similar the APIs exist on .NET
/// Framework 4.5, it implements a version of .NET Standard that isn't compatible with the library.
/// </summary>INetCoreApp10
class Example1
{
public void Net45Application(INetFramework45 platform)
{
// .NET Framework 4.5 has access to all .NET Framework APIs
platform.FileSystem();
platform.Console();
// This fails because .NET Framework 4.5 does not implement .NET Standard 1.3
// Argument 1: cannot convert from 'Analogy.INetFramework45' to 'Analogy.INetStandard13'
NetStandardLibrary13(platform);
}
public void NetStandardLibrary13(INetStandard13 platform)
{
platform.FileSystem();
platform.Console();
}
}
/// <summary>
/// This example shows a library targeting multiple frameworks and 2 different applications
/// using that library. MultipleTargetsLibrary needs access to the FileSystem, that API was only available
/// in .NET Standard 1.3. .NET Standard 1.3 only works with .NET Framework 4.6. Because of this
/// MultipleTargetsLibrary needs to add support for .NET Framework 4.5 explicitly.
/// </summary>
class Example2
{
public void Net45Application(INetFramework451 platform)
{
// On the .NET 4.5.1 application, the INetFramework45 implementation is choson
MultipleTargetsLibrary(platform);
}
public void NetCoreApplication(INetCoreApp10 platform)
{
// On the .NET Core 1.0 application, the INetStandard13 implementation is choson
MultipleTargetsLibrary(platform);
}
public void MultipleTargetsLibrary(INetFramework45 platform)
{
platform.FileSystem();
}
public void MultipleTargetsLibrary(INetStandard13 platform)
{
platform.FileSystem();
}
}
/// <summary>
/// This example shows how future platforms can be added without the need to change libraries that
/// target the .NET Standard. JSON.NET targets .NET Standard 1.0 and can run on *ANY* platform that implements
/// the standard.
/// </summary>
class Example3
{
/// <summary>
/// This future platform implements .NET Standard 1.3
/// </summary>
public void FuturePlatformApplication(ISomeFuturePlatform platform)
{
// You are able to use JSON.NET with the future platform without recompiling JSON.NET
JsonNet(platform);
}
/// <summary>
/// This method represents the implementation of JSON.NET. JSON.NET supports .NET Standard 1.0.
/// </summary>
public void JsonNet(INetStandard10 platform)
{
platform.Linq();
platform.Reflection();
platform.Collections();
}
}
}
@analogrelay
Copy link

analogrelay commented Apr 23, 2016

@awright18:

Or will someone still be able piece together what they want from individual packages?

Within the .NET Platform Standard, we still have the individual packages. In the end, Platform Authors still have the ability to piece together their own set of packages and make it work. However, the Standard creates a base on which Library Authors can develop, so Platform Authors are strongly encouraged to adopt a version of the Standard.

We call it a "Platform Standard" because it is a Standard, much like HTTP or TCP. You can take a few pieces of HTTP and implement them on your Server (Platform) and Clients (Libraries) that support your special version of the Protocol (Standard) will work. However, if you fully implement HTTP, then ANY HTTP Client (Library targeting the Platform Standard) can work with your Server (Platform). The great thing about .NET Core is that it's fully open-source and detached from Windows so you can do what you want with it. The .NET Platform Standard is about adding a layer of structure on top of that flexibility to make all our lives simpler :)

@fescoffier
Copy link

Awesome ! Thanks a lot !

@DavidBurela
Copy link

Which is why the new stuff starts at netstandard1.5

I really like @davidfowl idea during one of his presentations, that the older legacy versions start at 0.5 and the first real version starts at 1.0. Instead of 1.0 - 1.5.

@Northgates-Systems
Copy link

Thanks @davidfowl, explained it clearly and consisely. - I have been battling this for ages.

Moving into future in confidence.

@ealsur
Copy link

ealsur commented Apr 29, 2016

copy paste screenshot to Powerpoint That should do it on any dev oriented presentation this year :)

@dasMulli
Copy link

dasMulli commented May 8, 2016

@davidfowl Awesome work ;)
But what about netstandard1.6? I think this was added a few days ago and netcoreapp1.0 is now based on that.. NuGet/Home#2536

@colin-young
Copy link

While this explanation seems to be very clear and concise, there is one thing I don't understand: I currently have a project that targets .Net Platform 5.4 and has a dependency on System.Security.Cryptography.{Algorithms+Csp+Primitives}. My understanding is that I should now target netstandard1.3, but according to my understanding, I only get crypto if I target NetFramework4.5 or higher, and I won't get it with anything that targets core CLR. Is that correct? Something new since dnxcore50 days (when this project was originally created)?

@sandersaares
Copy link

sandersaares commented May 13, 2016

What is the authoritative place that defines what is in what .NET Standard version? Is there a place where I can easily see the differences between two versions? A change history of sorts?

@deepumi
Copy link

deepumi commented Jun 3, 2016

Wow, this is Awesome, In this case we would able to target as many platform we want like UWP or MONO or any standard .net platform.

@davidfowl, thank you.

@seangwright
Copy link

This is great! Despite watching the ASP.NET community standups every week I think this is the first time it has all clicked for me.

Thanks.

@richardgavel
Copy link

One thought. Shouldn't stuff like .NET Framework 4.5.2 in this visualization be considered classes, not interfaces? That makes more clear the distinction that .NET standard (or rather a version of it) is purely an "interface" that one or more frameworks implement.

@eanyanwu
Copy link

Wow ... this was oddly more helpful than normal sentences.

The .NETFramework,Version=4.6 framework represents the available APIs in the .NET Framework 4.6. [1]

Huh....?

The .NETStandard,Version=1.3 framework is a package-based framework. It relies on packages that target the framework to define and expose APIs in terms of the framework.[1]

Wut?
[1] https://dotnet.github.io/docs/core-concepts/packages.html

interface INetStandard10
    {
        void Primitives();
        void Reflection();
        void Tasks();
        void Collections();
        void Linq();
    }

AH. GOT IT. THANKS.

@jcob-ross
Copy link

Clicked, thanks! 🤘

@mduu
Copy link

mduu commented Jul 28, 2016

Clicked a lot! Thx. Additional explanations from @anurse rocked too!

@ArturKarbone
Copy link

Clicked. Thanks

@tthiery
Copy link

tthiery commented Sep 27, 2016

@davidfowl Can you give us an update. .NET Standard 2.0 needs an awesome explaination ;)

@adamralph
Copy link

I guess this has moved to https://github.com/davidfowl/NetStandard/blob/master/platforms.cs ?

FWIW I sent a PR to add 2.0 - davidfowl/NetStandard#10

@scottt732
Copy link

@zoltanarvai
Copy link

Clicked! I love it!

@valerysntx
Copy link

👍

/* IComparable<SemVer>? */
public class INetStandard13: IComparable, IComparable<INetCoreApp10>, IEquatable 
{
}
 
      

@bitbonk
Copy link

bitbonk commented Nov 30, 2016

This could need an update for .NET Standard 1.6 and maybe 2.0, even if it is not fully baked yet.

@mossyblog
Copy link

mossyblog commented Dec 7, 2016

The part that still concerns me is the vNext parts.. the fork in the road... let us pick on async/await ... now it's a pretty prolific thing to use in most "modern" .NET code today, however, Unity3D / WebGL, currently can't support this approach to multi-threading... now sure, one can argue "well, sux to be Unity3d and the world moves forward" however, all this does really is cap off a fork in the road, as in order for this to realistically work it needs some incentive or forcing function that encourages all ships to rise with the future tides in a uniform way (no boat gets left behind)... so how does one concede defeat on some areas where it just can't be brought forward due to technical or commercial limitations (lets for argument sake, assert Unity3D can't make task/parallel work because it conflicts with their IL2CPP output) on larger platform adoptees - such as Unity3D ...iOS etc.

The point is there will be commercial realities to face with the platform and how one triages that IF/ELSE statement is where I'm a little gun-shy from PCL abuse.

@jorgensigvardsson
Copy link

I find this very clear and concise. Thanks!

@Jasonlhy
Copy link

This is what I got using "generate class diagram" in visual studio.

classdiagram1

@stg609
Copy link

stg609 commented Feb 9, 2017

It makes more sense now! Thanks!

@devenshah
Copy link

Click! Click!

@peponeska
Copy link

What about netstandard2.0?

@Noctis-
Copy link

Noctis- commented Mar 27, 2017

consider changing "choson" to "chosen" ? :)

@Kralizek
Copy link

Really nice. I would suggest to use concrete classes to represent NetCoreApp10, NetCoreApp11 and the several .NET Frameworks like Net46 and Net47

@jsinh
Copy link

jsinh commented Jun 11, 2017

Makes sense, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment