Portable- is dead, long live NetStandard
With the RC of NuGet 2.12 for VS 2012/2013, and imminent release of .NET Core on Monday the 27th, it’s time to bid farewell to our beloved/cursed PCL profiles. So long, you won’t be missed! Oh, and dotnet
, please don’t let the door hit you on the way out either.
In its place we join the new world of the .NET Platform Standard and it’s new moniker netstandard
.
When dotnet
was released last July, there was a lot of confusion around what it is and how it worked. Working with the NuGet and CoreFX teams, I tried to explain it in a few of my previous posts. Despite good intentions, dotnet
was a constant frustration to many library authors due to its design and limited support. dotnet
only worked with NuGet v3, which meant that packages would need to ship a dotnet
version and a version in a PCL directory like portable-net45+win8+wp8+wpa81
to support VS 2012/2013.
It was hard to fault anyone for wondering, “why bother?” The other downfall of dotnet
, and likely the main one, was that dotnet
fell into a mess trying to work with different compatibility levels of libraries. What if you wanted to have a version that worked with newer packages than were supported by Windows 8? What if you wanted to have multiple versions which “light up” based on platform capabilities? How many of you who installed a dotnet
-based package, with its dependencies listed, saw a System.Runtime 4.0.10
entry and wondered why you were getting errors trying to update it? After all, NuGet showed an update to 4.0.20
, why wouldn’t that work? The reality was that you had to release packages with multiple versions that were incompatible with some platforms because there was no way to put all of it into one package.
Enter .NET Platform Standard
netstandard
fixes the short comings of dotnet
by being versioned. As of today, there’s 1.0 – 1.6, with the following TFM’s netstandard1.0
–netstandard1.6
. Now, the idea is that each .NET Platform Standard version supports a given set of platforms and when authoring a library, you’d ideally want to target the lowest one that has the features you need and runs on your desired target platform versions.
With NuGet 2.12, netstandard
is also supported in VS 2012 and 2013, so that there’s no further need to include a portable-*
version and a netstandard
version in the same package. Finally!
What does this all mean
The short answer is that if you currently have a Profile 259 PCL today, you can change your NuGet package to put it in a netstandard1.0
directory and add the appropriate dependency group. The full list if profile -> netstandard
mappings is here. If you support .NET 4.0 or Silverlight 5 in your PCL — basically a PCL “older” than 259, then you can continue to put that in your NuGet alongside the netstandard1.0
+ version and things will continue to work. In addition, a platform-specific TFM (like net45
) will always “win” over netstandard
if compatible.
Detour: Dependencies for NetStandard
Like dotnet
, netstandard
requires listing package dependencies. For the most part, it’s easier than with dotnet
as there is a meta-package, NETStandard.Library 1.6.0
(the RC2 version is 1.5.0-rc2-24027
), that has most BCL dependencies included. This package is one that you probably have in your project.json
today. Put the NETStandard.Library 1.6.0
dependency in a netstandard1.0
dependency group, along with any other top-level dependencies you have:
<dependencies>
<group targetFramework="netstandard1.0">
<dependency id="NETStandard.Library" version="1.6.0" />
<dependency id="System.Linq.Queryable" version="4.0.1" />
</group>
</dependencies>
Next steps
There’s about to be a lot to do over the coming weeks:
- Get the .NET Core 1.0 RTM with the Preview 2 tooling
- Download VS 2015 Update 3 when available
- Grab NuGet 2.12 for VS 2012/2013
Start updating your packages to support .NET Core if you haven’t already. If you’ve been waiting for .NET Core RTM, that time has finally come. You can either use a csproj
-based portable library targeting netstandard
or use xproj
with project.json
. As an aside, my personal opinion is that xproj
‘s main advantage over csproj
today is cross-compiling. If you need to compile for multiple targets, that’s the currently the best option, otherwise, you’ll get a better experience using the csproj
approach.
Converting existing PCL projects
VS 2015 Update 3 has a new feature that makes it easy to convert a PCL to netstandard
. If your library has any NuGet dependencies installed, you need to first follow the steps to switch packages.config
to project.json
. Once you do that, you can select Target .NET Platform Standard from the project properties and it’ll convert it over:
Icing on the cake
Xamarin supports all versions of netstandard
as well. This means that if you were cross-compiling because PCL 259 was too limiting, try taking another look at netstandard1.3
+. There’s a lot more surface area there and it may mean you can eliminate a few target platforms.
Bonus Round
If you want to use xproj
for its cross-compiling features and also need to reference that library from a project type that doesn’t support csproj
-> xproj
references today (most of them, including UWP don’t work super-well), I’ve written up an explanation of how you can do this on StackOverflow.
So this is all great, and I really appreciate you writing this up, and all your efforts to bring so much .NET code into the future with your NuSpec reference generator.
I tried to convert a project with the .NET Platform Standard using the dialog, and one thing became crystal clear very quickly: The UI does not help you one iota in understanding which .NET Standard Platform encompasses which target runtimes. When you’re on Portable, there is a list of targets (you can see it above the link in the screenshot above). When you target dotnetstandard… nothing. That has to change, before Update 3 RTM, if possible.
Yup, I agree that there needs to be more documentation and a “prettier” TL;DR version of the .NET Platform Standard docs that shows the key points.
Great post!
BTW, I remember I read another version somewhere else. What about “the harder way” ? Cos’ requiring just necessary dependencies instead of whole standard library sounds very attractive to me.
Great write up. Have converted a solution to xproj’s and so far finding VS a bit flaky with the latest bits. Intellisense in particular a bit random. Overall liking it. Less confusing than portable. But damned if I can get VSTS to build the solution even though it builds on the desktop… But that’s probably my fault.
Thanks Oren for Great post.
My code compiles from netstandard1.0 to netstandard1.5 on PCL.
But If I target netstandard1.6 then I received an error.
Your project is not referencing the “.NETPlatform,Version=v5.0” framework. Add a reference to “.NETPlatform,Version=v5.0” in the “frameworks” section of your project.json, and then re-run NuGet restore.
Anwar, I get the same. Did you get any resolution to this?
You can find solution for this problem here: https://github.com/dotnet/roslyn/issues/12918