Page 24 - MSDN Magazine, September 2017
P. 24
As you can see, the logic library has a value for TargetFramework of netstandard2.0, while the console app has a value of netcoreapp2.0. The TargetFramework property indicates which .NET implemen- tation you’re targeting. So, the console app is targeting .NET Core 2.0, while the library is targeting .NET Standard 2.0. That means you can reference the logic library not only from a .NET Core app, but also from an app built for .NET Framework or Xamarin.
Unfortunately, most of the libraries available today aren’t targeting .NET Standard, yet. Most of them are targeting the .NET Framework. Of course, not all libraries can (or even should) target .NET Standard. For instance, a library containing Windows Presentation Foundation (WPF) controls needs to target .NET Framework because UI isn’t part of the standard. However, many of the general-purpose libraries only target .NET Framework because they were created when .NET Standard simply didn’t exist yet.
With .NET Standard 2.0, the API set is large enough so that most, if not all, of the general-purpose libraries can target .NET Standard. As a result, 70 percent of all the libraries that exist on NuGet today only use APIs that are now part of .NET Standard. Still, only a fraction of them are explicitly marked as being compatible with .NET Standard.
To unblock developers from using them, a compatibility mode has been added. If you install a NuGet package that doesn’t offer a library for your target framework, nor provides one for .NET Standard, NuGet will try to fall back to .NET Framework. In other words, you can reference .NET Framework libraries as if they were targeting .NET Standard.
I’ll show you what this looks like. In my example, I’ll use a popu- lar collection library called PowerCollections, which was written in 2007. It wasn’t updated in a while and still targets .NET Framework 2.0. I’ll install this from NuGet into the hello app:
$ dotnet add package Huitian.PowerCollections
This library provides additional collection types that the BCL doesn’t provide, such as a bag, which makes no ordering guarantees. Let’s change the hello app to make use of it, as shown in Figure 6.
If you run the program, you’ll see the following:
$ dotnet run
hello.csproj : warning NU1701: Package 'Huitian.PowerCollections 1.0.0' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.0'. This may cause compatibility problems. 1
3
2
So, what just happened? The hello app is targeting .NET Core 2.0. Because .NET Core 2.0 implements .NET Standard 2.0, it also has the compatibility mode for referencing .NET Framework
Figure 6 Sample Application Using PowerCollections
libraries. However, not all .NET Framework libraries will work on all .NET implementations. For example, they might use Windows Forms or WPF APIs. NuGet has no way of knowing that, so it gives you a warning message so you’re aware of this situation and don’t waste your time troubleshooting issues that might result from this.
Note that you’ll get this warning each time you build. This avoids the problem where you simply didn’t see the warning during pack- age installation, or forgot about it.
Of course, there’s nothing worse than unactionable warnings that you need to overlook every time you build. So, the idea here is that after you validate your app, you can then disable the warning for that package. Because the app is running fine (it correctly printed the contents of the bag you created) you can now suppress the warning. To do that, edit the hello.csproj file and add the NoWarn attribute to the package reference:
<PackageReference Include="Huitian.PowerCollections" Version="1.0.0" NoWarn="NU1701" />
If you now run the app again, the warning should be gone. Should you install another package that uses the compatibility mode, you’ll get the warning for that package for which you can suppress, as well.
The new tooling also lets class library projects produce NuGet packages as part of the build.
The new tooling also lets class library projects produce NuGet packages as part of the build. This makes it much simpler to share your libraries with the world (by pushing to nuget.org) or just within your organization (by pushing to your own package feed on Visual Studio Team Services or MyGet). The new projects also support multi-targeting, which lets you build a single project for multiple .NET implementations. This means you can use conditional com- pilation (#if ) to adapt the library to specific .NET implementations. It also lets you build .NET Standard wrappers for platform-specific APIs. However, all of that is beyond the scope of this article.
Wrapping Up
.NET Standard is a specification of APIs that all .NET implemen- tations must provide. It brings consistency to the .NET family and enables you to build libraries you can use from any .NET imple- mentation. It replaces PCLs for building shared components.
.NET Core is an implementation of the .NET Standard that’s optimized for building console applications, Web apps and cloud servicesusingASP.NETCore.ItsSDKcomeswithapowerfultool- ing that in addition to Visual Studio development supports a full command line-based development workflow. You can learn more about them at aka.ms/netstandardfaq and aka.ms/netcore. n
Immo Landwerth is a program manager at Microsoft, working on .NET. He focuses on .NET Standard, the BCL and API design.
thanks to the following Microsoft technical experts for reviewing this article: Phillip Carter, Richard Lander and Maira Wenzel
using System;
using Wintellect.PowerCollections;
namespace hello {
class Program {
static void Main(string[] args) {
var data = new Bag<int>() { 1, 2, 3 }; foreach (var element in data)
Console.WriteLine(element); }
} }
20 msdn magazine
.NET Standard