For the impatient: TL;DR

.NET Standard is for sharing code. .NET Standard is a set of APIs that all .NET implementations must provide to conform to the standard. This unifies the .NET implementations and prevents future fragmentation. It replaces Portable Class Libraries (PCLs) as the tool for building .NET libraries that work everywhere.

Much bigger API Surface: We have more than doubled the set of available APIs from13kin.NET Standard 1.6to32kin.NET Standard 2.0. Most of them are existing .NET Framework APIs. These additions make it much easier to port existing code to .NET Standard, and, by extension, to any .NET implementation of .NET Standard, such as .NET Core 2.0 and the upcoming version of UWP.

.NET Framework compatibility mode: The vast majority of NuGet packages are currently still targeting .NET Framework. Many projects are currently blocked from moving to .NET Standard because not all their dependencies are targeting .NET Standard yet. That’s why we added a compatibility mode that allows .NET Standard projects to reference .NET Framework libraries. While this may not work in all cases (for instance, if the .NET Framework binaries use WPF) we found that70% of all NuGet packages on nuget.org are API compatiblewith .NET Standard 2.0. So in practice it unblocks many projects.

Consuming a .NET Standard library

Before we can consume the library, we need to create a project. Let’s create an empty ASP.NET Core application. In Visual Studio, create a new project and chooseASP.NET Core Web Application from the.NET Corecategory. Then chooseEmptyand make sureASP.NET Core 2.0is selected:

From the command-line, you can simply usedotnet newagain:

$ dotnet new web -o aspnetcore

Consuming a .NET Standard library works the same as any other library project: you simply reference it. In Visual Studio, right-click your web project and click onAdd|Reference…. Then choosemylibraryfrom theProjectstab.

From the command-line, you can usedotnet add:

$ dotnet add reference ../mylibrary/mylibrary.csproj

Now edit the fileStartup.csand change the invocation of theRunmethod as follows:

As a command-line user, you can achieve the same by usingdotnet add package:

$ dotnet add package Huitian.PowerCollections

The following warning is displayed after you installed the package:

NU1701: Package ‘Huitian.PowerCollections 1.0.0’ was restored using ‘.NETFramework,Version=v4.6.1’ instead of the project target framework ‘.NETStandard,Version=v2.0’. This package may not be fully compatible with your project.

This warning not only appears when installing the package, but every time you build. This ensures you don’t accidentally overlook it.

The reason for the warning is that NuGet has no way of knowing whether the .NET Framework library will actually work. For example, it might depend on Windows Forms. To make sure you don’t waste your time troubleshooting something that cannot work, NuGet lets you know that you’re potentially going off the rails. Of course, warnings you have to overlook are annoying. Thus, we recommend that you test your application/library and if you find everything is working as expected, you can suppress the warning.

If you’re using the command-line, edit your project file and add theNoWarnattribute on thePackageReferencethat you want to suppress the warning for. The value for the attribute is a comma separated list of all the warning IDs. In our case it’s only a single one, namelyNU1701:

In Visual Studio, right-click the package reference you want to suppress the warning for inSolution Explorerand selectProperties. Set theNoWarn property toNU1701as in the following example.

Building the project will now show zero warnings. Notice that the suppression isn’t global but specific to each package reference. This ensures that just using one library through the compatibility mode doesn’t result in a free ride for all future references. So if you install another library that needs the compatibility mode, you’ll get the warning again and you’ll need to suppress it for that package too.

Producing a NuGet package

When your library is ready, you can produce a NuGet package for it and publish it (I’m assuming that’s our goal). To do this in Visual Studio, right-click your project and selectProperties. On thePackagetab, check the box forGenerate NuGet package on build:

If you’re using the command-line, edit the project file and add theGeneratePackageOnBuildproperty with a value oftrue:

When you rebuild your project, you’ll also find a NuGet package in the output directory.

What about Portable Class Libraries?

If you’re sharing code between different .NET implementations today, you’re probably aware of Portable Class Libraries (PCLs). With the release of .NET Standard 2.0, we’re now officially deprecating PCLs and you should move your projects to .NET Standard:

Summary

.NET Standard 2.0 has doubled the APIs since .NET Standard 1.x, which means it’s now much easier to port existing code from .NET Framework to .NET Standard. It also adds a compatibility mode for referencing existing .NET Framework binaries from .NET Standard. This allows you to get started although not all of your dependencies have ported to .NET Standard yet.

Virtually all .NET implementations have support for .NET Standard 2.0, including .NET Framework, .NET Core, and Xamarin. UWP support will come later this year. All these implementations benefit from the added APIs and the compatibility mode, especially .NET Core and UWP, which used to have a much more constrained API set.

Are you building applications?Then, we recommend that you convert your business logic and UI-independent code to .NET Standard. This ensures no matter where your business needs to go — desktop, mobile, or cloud — your code can come along for the ride.

Are you building NuGet packages? Then move to .NET Standard 2.0. You get a lot of APIs without compromising on reach. And your consumers will love it too!

Tags

Join the conversation

Woohoo! What an accomplishment! Great work, team!!! Looking forward to finally testing this out. I do have to say I have been using the previews and have been massively impressed by the debugging experience in Visual Studio now. Things are starting to shape up for real and it’s good to see .NET Standard2.0 finally ship. MSFT is trending up these days! 🙂

Thanks! We’re also extremely excited about this release. We’re also very grateful for the amazing community we have. The amount of excellent & constructive feedback was immense. Without it, the product wouldn’t be half as good. Also, many community contributions made it into this release (not so much .NET Standard, but especially into .NET Core). I’m sure we’ll publish some stats

Hey good to see you here Mike!
Yep hopefully MS is def on the right track.

Looking forward to have XF implement the tool-set UWP and its toolkit have to offer. Then we have to see Mono for WASM, and there we have Silverlight back again working natively on any platform! How efin great is this!

Once the graphic primitives are implemented, I will start implementing higher level controls using them and from there, we should be able to create a branded experience across platforms. It somewhat flies in the face of what the Xamarin Forms team has expressed as a goal, but so far they haven’t out right rejected the proposal.

Consumption is, but you need an updated NuGet client which AFAIK will ship soon. If you want to build .NET Standard 2.0 libraries you need to use VS 2017 (15.3). You could, however, also just use the command line until you can upgrade your VS.

You also need to install the .NET Core 2.0 SDK — it’s not included by VS (only .NET Core 1.x is chained in today).

We’ll chain in .NET Core 2.0 in a later version of VS to make it easier. Reason it’s not chained today is that this allowed us to make changes to .NET Core 2.0 until the last minute without having to insert new bits in VS, which is fairly expensive.

I am unable to consume a .Net Standard 2.0 package in VS2015 (with the latest NuGet client v3.6.0) to a project targeting .Net Framework 4.6.1.
When trying to install the package it says “To reference a library that targets .NET Standard 1.5 or higher, you need to install the .NET Standard Build Support extension for the .NET Framework fromhttps://aka.ms/netstandard-build-support-netfx”

As Hunter said, we’ll have support for VB and F# as well. It’s just that in these announcements I try to keep it simple. I did separate out the VS vs. CLI experience but I didn’t want to add language into the mix as well. Otherwise, these blog posts become “read your own adventure”.

In general, I try to avoid mentioning any languages when talking about .NET Standard because it has zero impact on the programming language. However, for demos you obviously have to do something concrete. And the reason we use C# for the most part is simply because that’s what the majority of our customer uses.

I blog often and I truly appreciate your content.
This great article has really peaked my interest.
I will bookmark your blog and keep checking for new information about
once per week. I opted in for your RSS feed too.

Sorry about that. It sounds like your project is a Portable Class Library (PCL) that targets .NET Standard. I recommend that you create a new .NET Standard project and copy & paste the sources over, then deleting the PCL project. The PCL project type has several limitations which is why in 15.3 the ability to target .NET Standard from PCLs has been removed. If you need more help trouble shooting, simply shoot me an email at immol at ms dot com. Thanks!

I think we’re talking passed each other. Let me explain: in VS 2017 you had two ways to target .NET Standard: one was via letting a PCL target .NET Standard. The other was via the new .NET Standard project type. We’ve disabled the UI for letting a PCL target .NET Standard because it never worked well. It sounds like we’ve accidentally broken something else that affects existing projects.

However, you can use the .NET Standard project type, i.e. File | New Project | .NET Standard | Class Library (.NET Standard) to target .NET Standard 1.x which can still be consumed from .NET Core 1.x. Does this make sense?

It does. Since this am I have created a .Net Standard Library targeting .Net Standard 1.6 and it working great.

Thanks!

6 months ago

Tim

Recreating the projects did work properly for me as well. Looking at the contents of the .csproj file it looks like they have been reduced quite a bit. Out of curiosity are there any blog posts planned covering how such a reduction was achieved?

These new projects are called SDK-style projects (you see an Sdk attribute at the root of the project XML element). This is what enables the reduction. Conversely, there is a new project system in Visual Studio (a project system is what is responsible for showing the file structure in solution explorer and provides the commands that interact with the project). The new .NET Core, .NET Standard, and ASP.NET Core projects are SDK-style projects. By editing that TargetFramework property you can also use them to target .NET Framework (e.g. but putting net461). However, not all features from the old project system work, for instance, no UI designers will work.

On the step “Add | Reference…. Then choose mylibrary from the Projects tab.”
I can’t see myLibrary in the list in the Reference manager. When I select browse, it only allows me to pick files of type Component Files, so I can’t select my csproj to select it. (I can see in File Explorer that myLibrary.csproj does exist, however)

Hey Michele, excellent point. My walk through assumes that you either start & stay in VS or that you start & stay on the command-line. If you created the projects on the command line, then there is no solution that references both projects yet. You can either create the solution in VS and add the projects as an existing project (as you did) or create the solution using the command-line, which looks like this:

Thank you, Michele! For the life of me, I could not figure out what i was doing wrong or what I had set up incorrectly. Something so simple and straightforward had confounded me for a full day! Have a great day!

The build might fail if the library exposes APIs that don’t exist in .NET Standard 2.0. However, if those usages only occur in the implementation, then building along will generally not detect this case. However, you can use static analysis to find out whether the NuGet package you’re using is compatible with .NET Standard 2.0 by using API Port. Check out this video that walks you through that.

Unfortunately, this feature isn’t available. You’ll need to create a new project and copy & paste the source files over. If you’re comfortable editing the .csproj directly, you can also do that. That requires that you’re familiar with how the old & new format looks like, but it can be a much more efficient way to convert a large amount of projects.

Thank you for you response. One more question. I saw on the announcing .Net Framework 4.7 page conflicting statements which I feel need clarification. “You can reference .NET Standard 1.0 through 1.6 class library projects from .NET Framework 4.7 projects.” and ” .NET Standard 2.0 class library projects and NuGet packages start being created, you’ll be able to reference them from .NET Framework 4.6.1 or later projects.”.
The first statement limits .Net 4.7 to 1.0 through 1.6.
The second statement says Standard 2.0 for 4.6.1 and later which would include 4.7.
So can Standard 2.0 be referenced by .Net 4.7 or not?

The story is quite simple: .NET Framework 4.6.1 has support for .NET Standard 2.0, which includes all future versions of .NET Framework as well. The only interesting point is that .NET Framework 4.7.1 has the support “built-in” while for .NET Framework 4.6.1, 4.6.2, and 4.7 the application has to deploy additional files. However, MSBuild will copy the necessary files to your application’s output folder.

Here’s the link https://blogs.msdn.microsoft.com/dotnet/2017/04/05/announcing-the-net-framework-4-7
It is taking time to figure out what can and cannot be done.
Seems that .Net 4.6.1 and later can reference/consume a .Net Standard 2.0 library, but .Net Standard 2.0 may not be able to consume a .Net library of any other version.
For example, I have a wrapper class around SqlClient. I was hoping that I could port to .Net Standard 2.0, but since the SqlCommandBuilder class is not available therefore my code cannot be ported yet.

This does not work when the library is used by a .NET 4.x application and other .NET 4.x assemblies (e.g. WPF) reference the “System.ComponentModel.DataAnnotations” library. With PCL libraries this works correctly.

Yes, but that has nothing to with API surface like DataAnnotations. .NET Standard as a whole isn’t supported by .NET Framework prior to 4.5 and .NET Standard 2.0 requires 4.6.1 and up.

6 months ago

jbe2277

Please just replace “.NET 4.x” with “>= .NET 4.6.1” assemblies in my text. The issue still remains. I cannot reuse a .NET Standard 2.0 library which needs DataAnnotations correctly in a .NET 4.6.1 application with other non .NET Standard assemblies which reference the classic “System.ComponentModel.DataAnnotations”. Some of them are 3rd party assemblies so I cannot replace DataAnnotations with NuGet package version.

The only caveat is that you need to install the System.ComponentModel.Annotations in the application project as well. This makes sure the .NET Framework DataAnnotation types are unified with the types consumed by .NET Standard library (in other words, the NuGet package adds some type forwards that are required at runtime).

You do not have to change the existing .NET Framework binaries/NuGet packages you consume. You only need to install the package into the application project. Also, make sure automatic binding redirects are enabled.

6 months ago

jbe2277

Thank you very much. The missing part was to install System.ComponentModel.Annotations in the application project as well. Now it’s working. 🙂

NoWarn disables the warning regarding a package only in the project (let’s call it ProjA) that directly references it. But the warning still appears in other projects which reference ProjA, one for each project. This is not the behavior I would expect.

What is the support story for calling WinRT apis from .Net Standard libraries? In the full framework, you can add a reference to Windows.Winmd and some supporting nuget packages, but that appears to be broken in .Net Standard. I presume that was intentional, so what is the future of that scenario?

.NET Standard is about writing class libraries that work across all .NET implementations. So for the most part, we don’t offer platform specific APIs. This includes WinRT but also extends to the iOS and Android APIs. For those, you want to create libraries that target the respective platforms. For WinRT, this would be File | New | Project | Windows Universal | Class Library (Universal Windows).

By the way, but a little offtop: Immo, you’re talking about targeting UWP when creating a library which needs to consume WinRT APIs. But many of these APIs can be called from a classic desktop app. However, it has always been tricky to reference a winmd metadata from such a project (especially if it was .Net Core on top of .Net Framework runtime). As Tim mentioned, we had to use third-party packages containing winmd file. Has anything changes since than for this scenario?

That is a very good point, actually. During Windows 8, we cut short the investment to make consuming WinRT APIs easy from .NET Framework (AFAIR some of the work was cut by yours truly) and we have not really revisited this since then. We should probably revisit that in a future update.

When it comes to .NET Core running on Windows and being able to all WinRT: that’s also a good point. I recently had a discussion with the runtime team about this. We believe the runtime should “just work” (e.g. WinRT-style COM activation and projections) but we haven’t really tested that scenario outside of UWP and don’t even produce the necessary assemblies for .NET Core. Again, we should probably revisit this. Would you mind filing a request on the CoreFX repo? It makes our lives a bit easier if we know who asked for it so we can follow up more easily later.

During the beta of .NET Standard 2.0 the only way to be able to create .NET Standard 2.0 class libraries was, as far as I know, by installing .NET Core 2.0 SDK which I could accept as it was after all a beta product.

After the release of .NET Standard 2.0 I would however expect a much cleaner cut, but it seems that we still have to install the .NET Core 2.0 SDK to be able to create a .NET Standard 2.0 class library for use from e.g. a .NET Framework 4.6.1 project. Is that correct?

Looking for a new job with good salary seems to get a difficult task nowadays.
However, each time a blogger does enjoy what he writes about, he’ll probably stay
with it for a time. A blog writing service knows how to spark the eye
to your services, that will drive increased traffic and result in higher revenues for
your small business.

Assets file ‘C:\myLibraryConsumerExample\myLibraryConsumerExample\obj\projectassets.json’ doesn’t have a target for ‘.NETCoreApp,Version=v2.0’. Ensure that restore has run and that you have included ‘netcoreapp2.0’ in the TargetFrameworks for your project.