Writing smarter cross-platform .NET Core apps with the API Analyzer and Windows Compatibility Pack
There's a couple of great utilities that have come out in the last few weeks in the .NET Core world that you should be aware of. They are deeply useful when porting/writing cross-platform code.
.NET API Analyzer
First is the API Analyzer. As you know, APIs sometimes get deprecated, or you'll use a method on Windows and find it doesn't work on Linux. The API Analyzer is a Roslyn (remember Roslyn is the name of the C#/.NET compiler) analyzer that's easily added to your project as a NuGet package. All you have to do is add it and you'll immediately start getting warnings and/or squiggles calling out APIs that might be a problem.
Check out this quick example. I'll make a quick console app, then add the analyzer. Note the version is current as of the time of this post. It'll change.
C:\supercrossplatapp> dotnet new console
C:\supercrossplatapp> dotnet add package Microsoft.DotNet.Analyzers.Compatibility --version 0.1.2-alpha
Then I'll use an API that only works on Windows. However, I still want my app to run everywhere.
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var w = Console.WindowWidth;
Console.WriteLine($"Console Width is {w}");
}
}
Then I'll "dotnet build" (or run, which implies build) and I get a nice warning that one API doesn't work everywhere.
C:\supercrossplatapp> dotnet build
Program.cs(14,33): warning PC001: Console.WindowWidth isn't supported on Linux, MacOSX [C:\Users\scott\Desktop\supercr
ossplatapp\supercrossplatapp.csproj]
supercrossplatapp -> C:\supercrossplatapp\bin\Debug\netcoreapp2.0\supercrossplatapp.dll
Build succeeded.
Olia from the .NET Team did a great YouTube video where she shows off the API Analyzer and how it works. The code for the API Analyzer up here on GitHub. Please leave an issue if you find one!
Windows Compatibility Pack for .NET Core
Second, the Windows Compatibility Pack for .NET Core is a nice piece of tech. When .NET Core 2.0 come out and the .NET Standard 2.0 was finalized, it included over 32k APIs that made it extremely compatible with existing .NET Framework code. In fact, it's so compatible, I was able to easily take a 15 year old .NET app and port it over to .NET Core 2.0 without any trouble at all.
They have more than doubled the set of available APIs from 13k in .NET Standard 1.6 to 32k in .NET Standard 2.0.
.NET Standard 2.0 is cool because it's supported on the following platforms:
- .NET Framework 4.6.1
- .NET Core 2.0
- Mono 5.4
- Xamarin.iOS 10.14
- Xamarin.Mac 3.8
- Xamarin.Android 7.5
When you're porting code over to .NET Core that has lots of Windows-specific dependencies, you might find yourself bumping into APIs that aren't a part of .NET Standard 2.0. So, there's a new (preview) Microsoft.Windows.Compatibility NuGet package that "provides access to APIs that were previously available only for .NET Framework."
There will be two kinds of APIs in the Compatibility Pack. APIs that were a part of Windows originally but can work cross-platform, and APIs that will always be Windows only, because they are super OS-specific. APIs calls to the Windows Registry will always be Windows-specific, for example. But the System.DirectoryServices or System.Drawing APIs could be written in a way that works anywhere. The Windows Compatibility Pack adds over 20,000 more APIs, on top of what's already available in .NET Core. Check out the great video that Immo shot on the compat pack.
The point is, if the API that is blocking you from using .NET Core is now available in this compat pack, yay! But you should also know WHY you are pointing to .NET Core. Work continues on both .NET Core and .NET (Full) Framework on Windows. If your app works great today, there's no need to port unless you need a .NET Core specific feature. Here's a great list of rules of thumb from the docs:
Use .NET Core for your server application when:+
- You have cross-platform needs.
- You are targeting microservices.
- You are using Docker containers.
- You need high-performance and scalable systems.
- You need side-by-side .NET versions per application.
Use .NET Framework for your server application when:
- Your app currently uses .NET Framework (recommendation is to extend instead of migrating).
- Your app uses third-party .NET libraries or NuGet packages not available for .NET Core.
- Your app uses .NET technologies that aren't available for .NET Core.
- Your app uses a platform that doesn’t support .NET Core.
Finally, it's worth pointing out a few other tools that can aid you in using the right APIs for the job.
- Api Portability Analyzer - command line tool or Visual Studio Extension, a toolchain that can generate a report of how portable your code is between .NET Framework and .NET Core, with an assembly-by-assembly breakdown of issues. See Tooling to help you on the process for more information.
- Reverse Package Search - A useful web service that allows you to search for a type and find packages containing that type.
Enjoy!
Sponsor: Get the latest JetBrains Rider preview for .NET Core 2.0 support, Value Tracking and Call Tracking, MSTest runner, new code inspections and refactorings, and the Parallel Stacks view in debugger.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
https://github.com/dotnet/corefx/blob/master/src/System.Console/src/System/ConsolePal.Unix.cs#L253-L263
The setter throws a PlatformNotSupportedException. But you don't use the setter in your code.
Looks like your tool is wrong. The getter of WindowWidth is supported on Linux
Fair point, while that's a known issue we haven't noticed that it affects our demos :-)
MCDvoice Survey is McDonald’s survey of their customers mcdvoice survey
Comments are closed.
Or is it just a full rewrite?