Updated version for Visual Studio 2017 can be found here.
Recently I needed to create a library that would be shared between an UWP application and a Winforms application. My first thought was to create a portable class library with a profile that covered .NET 4.5.1 and Windows 10 which actually works out to be Profile44. At some point I was reminded of the new .NET Standard Library and decided that would be a better option.
.NET Standard Library
The .NET Standard Library specifies what .NET APIs are available based on the version of the .NET Standard Library being implemented. The following is a comparison to portable class libraries that really helped me understand the difference. This was pulled form the .NET Standard Library link above.
.NET Standard Library can be thought of as the next generation of Portable Class Libraries (PCL). The .NET Standard Library improves on the experience of creating portable libraries by curating a standard BCL and establishing greater uniformity across .NET runtimes as a result. A library that targets the .NET Standard Library is a PCL or a “.NET Standard-based PCL”. Existing PCLs are “profile-based PCLs”.
The .NET Standard Library and PCL profiles were created for similar purposes but also differ in key ways.
- Defines APIs that can be used for binary code sharing.
- The .NET Standard Library is a curated set of APIs, while PCL profiles are defined by intersections of existing platforms.
- The .NET Standard Library linearly versions, while PCL profiles do not.
- PCL profiles represents Microsoft platforms while the .NET Standard Library is agnostic to platform.
.NET Standard Library Project Type?
Since I need to use my library in a winforms and UWP applications I need to create a csproj based library and not a xproj based library. This part of the process that took me the longest to figure out. Thankfully this Stack Overflow post helped clear up what is required. Basically if any of your projects need to use msbulid (which both winforms and UWP do) then your library should be csproj based.
Create a Portable Class Library
For csproj based .NET Standard library we must start with a Portable Class Library project type. To start click File > New Project which shows the New Project dialog.
Locate the Class Library (Portable) type of project. Here I am using the C# version. Click OK. Next the Add Portable Class Library dialog will be shown.
Since this well be converted to use .NET Standard your selections don’t mean much here, but you will have to keep your target platforms when selecting which version of the .NET Standard your library will support. Click OK and the project will be created.
Convert a Portable Class Library to .NET Standard
Right click on your project and select properties. Alternately select the project in Solution Explorer and use the Project > [Project Name] Properties menu.
In project properties on the Library tab there is a link for Target .NET Platform Standard in the Targets section just below the Change button. Click the link.This will show a warning message about saving changes and that the available APIs could change. Click yes to continue.
This will return you back to the library page of the project’s properties with the PCL related options replaced with a drop down used to select the version of the .NET Standard you want your library to target. I am going with version 1.2 based on where I need my library to run. Use the .NET Platform Support section of this page to help you decided on the proper version of the .NET Standard for your library.
Save the project and it will now produce a .NET Standard library when built!
It is hidden by default, but if you show all file you will see that the project now contains a project.json file which means the project can be used by the .NET CLI. Open a command prompt in the project directory. The following command can be used to build the project.
Or if you would like to create a Nuget package you can use the following.
Inspecting the resulting dll in dotPeek
Just out of curiosity I wanted to see what showed when I opened up my .NET Standard library using a decompiler. I used dotPeek which is a free .NET decompiler created by JetBrains the company behind ReSharper.
As you can see in the following screenshot the platform shows as .Net Framework v4.6.1.
Now here is a screenshot of the same library on a computer with an older version of .NET and it show a platform of .Net Framework v4.0.
For some reason I was surprised by the fact the platform changed, but when I thought about it more I realized how else could it work because the library isn’t build to a specific platform. Seeing the platform change for the same library between two different machines really solidified how awesome the .NET Standard is.
As I said before I was hoping to use a .NET Standard library between a winform and UWP application. I did all the thing above and things were looking great. I added a project reference to my UWP application in Visual Studio 2015 with no trouble. Unfortunately the winforms application is stuck on Visual Studio 2013 (due to performance issue, 2015 is painfully slow with this solution) and Visual Studio 2013 doesn’t support this project type making a project reference impossible.
I could have gotten the library to work by adding it to the winforms solution as a Nuget reference, but for this project that was not a viable solution.