the how-dare-you-call-me-an-idiot’s guide to the .net standard (ndc london 2017)
TRANSCRIPT
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