A few days ago, Microsoft has released .NET Standard 2.0, which is the new dreams-come-true platform for libraries. Additionally, Portable Class Libraries (PCL) have since also been deprecated. Therefore, it’s about time to port my existing libraries.
In addition, also Visual Studio 2017 Version 15.3 with full support for .NET Standard 2.0 was released, as well as the latest Windows 10 Fall Creators Update Preview SDK. So, let’s get started!
.NET Standard vs. UWP
However, it turns out that UWP doesn’t yet support .NET Standard 2.0. For the UWP platform, the latest supported .NET Standard version is still 1.4, which is considerably less powerful.
Attempting to reference a .NET Standard 2.0 library from an UWP app leads to errors, including the following that gives it away:
Project '...' targets '.NETStandard,Version=v2.0'. It cannot be referenced by a project that targets 'UAP,Version=v10.0.10240'.
Upgrading the UWP project to the latest SDK Preview for the Windows 10 Fall Creators Update Build 16257 doesn’t change anything; both the SDK and the new Visual Studio 2017 version 15.3 can not yet use .NET Standard 2.0 in conjunction with UWP. According to Microsoft, that will be coming soon with the next UWP version.
.NET Standard 1.4 … for now!
As such, the latest possible version of .NET Standard that also supports UWP is v1.4. As this older version has the same platform compatibility (Linux, Mac and iOS and Android through Xamarin), I saw no harm in keeping the NFC library at the .NET Standard 1.4 for now.
A new library version based on .NET Standard 2.0 can be released later once the tooling is complete; even though that will most likely limit the use of that specific version to the Windows 10 Fall Creators Update. Which would mean that for maximum library compatibility, it’s better to stay at .NET Standard 1.4, or to include both versions into the same NuGet package. We’ll see.
Creating NuGet Packages through Visual Studio
Another convenient new feature of the latest Visual Studio version is that it now supports creating NuGet packages. Through a convenient visual editor interface, it’s now a lot easier for library authors to create the required .nuspec
files that define the library properties.
However, it wasn’t so easy after all. Several things are interesting and important to know:
Title / Product
So far, the .nuspec
files usually had a <title>
tag; I had that defined as:
<title>NFC / NDEF Library for Proximity APIs</title>
This tag is not present in the editor. However, Visual Studio offers a <Product>
tag, so I put the text there instead.
When building the project, Visual Studio generates the .nuspec
file in the /obj/
directory.
Looking into this file, it’s curious to see that the generated file neither has a <title>
, nor a <product>
tag. The name of the library simply isn’t present in the generated file; only the package ID is used. This issue has already been reported to the Visual Studio team and is being investigated.
The NuGet web site still shows the title on the package web page. However, within the NuGet Package Manager in Visual Studio, the title is gone:
The nuspec file documentation still lists that the <title>
is the human-readable name that’s also used within the Visual Studio NuGet Package Manager.
This situation isn’t ideal, as the package ID (currently “NdefLibrary”) can’t be changed easily. The package ID of my library doesn’t include the term “NFC”. As Visual Studio seems to ignore the package title, in the search other packages with a handful of downloads are ranked higher than the NdefLibrary:
I’m wondering if there is a way around this. For now, I’ve kept my manual .nuspec
file with the title, so that it’s shown at least on the NuGet website. I’ve also reported the issue to the Visual Studio Feedback tool.
Assembly Neutral Language
Another tricky thing is the Assembly Neutral Language. By default, the property is not set in the Visual Studio wizard. And you won’t notice that anything is missing for a long time: you can package the library, publish it to NuGet, reference it in a UWP app and test that app locally. Only when you try to package the app for submitting to the store, you will suddenly get the error message:
1>...\lib\netstandard1.4\NdefLibrary.dll : warning MSB3817: The assembly "...\lib\netstandard1.4\NdefLibrary.dll" does not have a NeutralResourcesLanguageAttribute on it. To be used in an app package, portable libraries must define a NeutralResourcesLanguageAttribute on their main assembly (ie, the one containing code, not a satellite assembly).
That’s a bit of a surprise. The wizard interface of Visual Studio is a language drop down, so simply choose “English”. The value is saved in the .csproj
file, where it is then written as “en”.
Just make sure you always select the neutral language, so that you don’t run into issues much later! See my Visual Studio feedback report for further details.
Symbol Packages
The third issue with the auto-generated nuget packages is that they only contain the final .dll
file, but not the .pdb
file that libraries should publish to the symbol server to make debugging easier for library users.
In the ideal case, the library package also includes the source code, so that developers that have issues can directly see what’s happening within the library.
The code in the .nuspec
file needs to be written manually in order to include these additional items – the auto-generated version by Visual Studio would only include the .dll
, nothing else.
The relevant part from the NFC / NDEF library .nuspec
:
<files> <file src="D:\Source\GitHub\ndef-nfc\NdefLibrary\NdefLibrary\bin\Release\netstandard1.4\NdefLibrary.dll" target="lib\netstandard1.4\NdefLibrary.dll" /> <file src="D:\Source\GitHub\ndef-nfc\NdefLibrary\NdefLibrary\bin\Release\netstandard1.4\NdefLibrary.pdb" target="lib\netstandard1.4\NdefLibrary.pdb" /> <file src="D:\Source\GitHub\ndef-nfc\NdefLibrary\NdefLibrary\**\*.cs" target="src\NdefLibrary" exclude="**\TemporaryGeneratedFile*.cs;NdefLibrary\obj\**\*.*" /> </files>
My Visual Studio UserVoice suggestion for improving the wizard is here – please vote if you also feel this could be improved!
Publishing the Package to NuGet Servers
Now that the NuGet package is created, you can finally publish the package to the NuGet servers.
The instructions for publishing a package including a symbol package for debugging are not fully up-to-date, however. The current NuGet versions always require specifying a source. They don’t default to the NuGet servers anymore.
In case you have two packages in the same directory – the normal one that goes to the NuGet server (NdefLibrary.4.1.0.nupkg), as well as the symbol package (NdefLibrary.4.1.0.symbols.nupkg), the tool will automatically find the symbol package and push that to the corresponding server without you having to specify that.
Pushing the library *and* the symbol package therefore works with the following command – also see my comment at the Microsoft Docs:
nuget push .\nupkg\NdefLibrary.4.1.0.nupkg -source https://www.nuget.org/api/v2/package
It is a bit strange that the NuGet server has to be specified, but the symbols server is then implicitely assumed. However, as that’s what will be intended in nearly all use cases, it’s fine for me.
Within a few minutes after publishing, the new library is live on the NuGet and the symbol servers!