The how-dare-you-call-me-an-idiot’s guide to the .NET Standard (NDC London 2017)

Preview:

Citation preview

What is the .NET Standard?

A specification defining a versioned set of APIs that are guaranteed to be implemented by a .NET platform

If a library targets the standard, it runs on all supporting platforms

Not the whole storyWhat APIs are included?

What are the different versions?

What about compatibility with existing frameworks and libraries?

How does it relate to .NET Core? Portable Class Libraries?

How does it work?

What’s the deal with .NET Standard 2.0?

What are we trying to solve?What are we trying to solve?

History lesson

.NET is multiple frameworks

.NET Framework, .NET Core, Silverlight, Windows Store, Windows Phone, Xbox, Mono, Xamarin, .NET Compact Framework, .NET Micro Framework, …

Different implementations over time(15 years…)

API Incompatibilities

So how do we share libraries across .NET implementations?

.NET Standard

Defines the APIs that all platforms must implement

Libraries target the specification, run on supporting platforms

Isn’t that just Portable Class Libraries?WAITWAIT

Isn’t that just Portable Class Libraries?

Portable Class Libraries

Libraries that target “profiles”, not frameworks

Profiles are API subsetsIntersection of targeted frameworks and versions

But, arcane - profile numbers? ¯\_(ツ)_/¯

Not scalable - new APIs, versions or frameworks require new profiles

.NET Standard flips the PCL model

PCLs find common ground between implementations

.NET Standard defines the minimum requirementsof an implementation

Libraries target the standard, run on supporting platforms

Even NEW platforms

.NET Standard is a specification.NET Standard is a specification

Not a Word document

Binary specification - a set of reference assemblies to compile against

Versioned NuGet package - NETStandard.Library

New versioned target framework - “netstandard”netstandard1.x, netstandard2.0

Target frameworks

NuGet has Target Framework Monikers - net46, netcoreapp1.0, win8, etc.

Depend on NuGet package, but target a version of a framework (net46, net35, net20)TFM decides what is referenced

Target framework specified in project settings

Target framework as “platform”

.NET Framework and .NET Core are concrete platformsApps run on these platforms

.NET Standard is an abstract platform Cannot run code on .NET Standard

Libraries target:

netstandard as an abstract platformRun on any supporting concrete platform

Concrete platformsSuperset of .NET Standard, with platform specific APIs

Apps target:

Concrete platformsImplements the abstract platform

VersioningVersioning

Versioning is additive

.NET Standard only adds APIs

No process for removing APIs

Adds assemblies, types and type members

2.0

1.6

1.5

1.4

1.3

1.2

1.1

New versions are supersets of all previous versions

Newer platforms can consume libraries targeting older standard versions

1.0

How did we get so many versions so quickly?How did we get so many versions so quickly?WAITWAIT

.NET Standard introduced with .NET Core 1.0

Back ported to earlier platforms for compatibility

What version of .NET Standard should I use?

A higher version will have more APIs

A lower version will have more platforms

Target the lowest version you can

API availability

github:dotnet/standard - docs/versions.md

apiport/portability analyser

How do APIs get added?

Review board - .NET Team, Xamarin and UnityPlatform implementers

Not everything will be added to standard

Out of band packages Pure IL, based on .NET Standard

Criteria - ubiquitous, mature, runtime specific (SIMD)

Packaging the standardPackaging the standard

NETStandard.Library package

v1.5, v1.6, v1.6.1 - package version, not standard version!

New TFMs - netstandard1.x, netstandard2.x

Target framework decides what version of reference assemblies are referenced

Demo

NuGet Package Explorer

Package version vs TFM version

Meta-package - all in the dependencies

1.x - fine grained package dependencies

What about .NET Standard 2.0?

What about .NET Standard 2.0?

Work in progress - shipping with VS2017

Loads more APIs

Consolidating reference assembliesnetstandard.dll

Consolidating packagesNo dependencies for NETStandard.Library

SAME GOALSSAME GOALS

“100% source and binary compatibility for classic .NET Framework and Xamarin assemblies

and existing PCLs"

–dotnet/standard/docs/netstandard-20/README.md

What was wrong with 1.x?

Not enough libraries targeting .NET Standard or PCLs

Majority of NuGet packages target .NET Framework

Tightly coupled to .NET Core

Cannot evolve .NET Core separately

Not enough APIs - “API cleanup went a bit overboard”

Adding missing APIs

Porting applications to .NET Core was too hard

Intersection of .NET Framework and Mono/Xamarin

Platform specific APIs?

Most excluded

Some APIs included: emulate or throw at runtime

netstandard.dll

Single reference assembly

Contains ALL APIs

The specification is monolithic, why are the reference assemblies fine grained?

Implications on packaging, implementation and backwards compatibility

Split with .NET Core

Previously built from .NET Core source

Now has own repo - dotnet/standard

.NET Core implements standard No longer “special”

Deprecating fine grained packagesImplications for deployment

How does it work?How does it work?

Reference assemblies

Type forwarding

Reference assemblies

Passed to compiler to define available APIsCompiler error if API is missing

Compiler not interested in implementation

Reference assemblies use empty typesEmpty methods, return null/default(T)

Implementation assemblies

Resolved at runtime

Contains the actual implementation

Must contain AT LEAST referenced types and members Can contain more APIs

Assemblies in the Microsoft.NET folder are implementation assemblies

Visual Studio uses reference assemblies to target 4.0, 4.5, 4.6.1, 4.6.2, etc. E.g. C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2

.NET Standard uses reference assemblies in NuGet package(s)

Assembly qualified names

Compiler embeds type reference as assembly qualified nameE.g. System.Threading!System.Threading.Timer

Runtime uses assembly name to resolve type

How to deal with platform implementation differences?E.g. mscorlib!System.Object, System.Runtime!System.Object

Type forwarding

Assembly attribute redirecting type implementation to another assembly[assembly: TypeForwardedTo(typeof(MyNamespace.MyType))]

Cannot rename, only redirect Must be in same namespace

Redirects at runtime

Also redirects at compile time

Type forwarding

Allows referencing type in one assemblyBut implementing in another

Useful for platform differences, or refactoring the platform

.NET Standard

API is defined in reference assemblies included in NuGet package

1.x libraries will reference types in System.*.dll

Each platform can type forward to implementation

What can reference what?

.NET Standard 1.x

References embedded as System.*.dll

Compile time (library)

References embedded as System.*.dll

no compile errors

Compile time (library)

References embedded as System.*.dll

no compile errors

Compile time (library)

Possibly more APIs than .NET Standard 1.x Microsoft.NETCore.Portable.Compatibility

package adds reference assemblies

NuGet understands mapping between platform and net

standard, e.g. net46 and netstandard1.3

Compile time (app)

Everything references System.*.dll

no compile errors

Compile time (app)

Platform includes System.*.dll reference assemblies. Forward to

mscorlib.dll

No compile errors

Compile time (app)

.NET Core implementation

assemblies match .NET Standard references

Run time

Runtime assemblies type forward .NET

Standard System.*.dll references to real implementation

Run time

.NET Standard 2.0

Types referenced as netstandard.dll

Compile time (library)

For 2.0, references match (netstandard.dll)

No compile errors

Compile time (library)

For 1.x, types embedded as System.*.dll

Compile time (library)

NETStandard.Library includes System.*.dll facades that type forward to netstandard.dll - no compile errors

System.*.dll references forwarded

to netstandard.dll

Additional package no longer necessary as types added back

Compile time (library)

References embedded as mscorlib.dll

NETStandard.Library includes mscorlib.dll facade that type forwards to netstandard.dll - no compile errors

Compile time (library)

References are to netstandard.dll - no

compile error

Compile time (app)

Transient references to mscorlib.dll

Compile time (app)

NETCoreApp package includes NETStandard.Librarymscorlib.dll facade forwards to netstandard.dll

- no compile errors

netstandard.dll references forward to

mscorlib.dll!

Compile time (app)

Transient mscorlib.dll and System.*.dll

references provided by platform

Compile time (app)

Runtime netstandard.dll

forwards to implementation

Run time

.NET Core 2.0 includes own netstandard.dll type forwards to real implementation

Requires netstandard.dll to

forward to mscorlib.dll

Run time

.NET Standard 1.x can reference:

.NET Standard 1.x assembly

PCL assembly

.NET Standard 2.0 can reference:

.NET Standard assembly

PCL assembly

.NET Framework assembly

NuGet knows mapping between platforms and .NET Standard versions

Allows referencing .NET Framework libraries from .NET Standard platforms

.NET Standard

Specification for available APIs across platforms

Replacement for PCLs

2.0 is adding back APIs, adding compatibility shims

Links

github: dotnet/standard

@terrajobst’s videos on YouTubehttp://bit.ly/netstandard_videos

myget: dotnet-coreNETStandard.Library2

@citizenmatt

Recommended