.NET Core and .NET Framework Working Together, Or: The Magic of .NET Standard

Today’s header image was created by Jo Szczepanska at Unsplash

Back when the first version of .NET Core was released, we were told that not everything that was present in .NET Framework would be present in .NET Core. In fact a lot of it was missing in the initial RTM release (as well as the earlier releases)

for a reminder of what we had available, take a look at my first post on .NET Standard

Initially, a lot of .NET Framework developers thought something along the lines of:

What’s the point of building a greenfield application in .NET Core if most of the .NET Framework APIs aren’t present?

In fact, I’d heard this being grumbled during a talk that I gave on .NET Core around the time of the 1.1 release.

I wrote about the 1.1 release, too

And it’s not hard to see why. Taking a look at the new APIs that are available with .NET Standard 2.0, you can see what was missing in .NET Standard 1.0:

Net Standard 2.0 included APIs slide
Source: https://sec.ch9.ms/sessions/c1f9c808-82bc-480a-a930-b340097f6cc1/build/2017/B8001.pptx

But now that we have access to all of the above APIs in .NET Standard 2.0, we can make some even more interesting .NET Core applications. In fact, during the talk that Scott Hanselman and Scott Hunter gave at Build 2017 entitled “Three Runtimes, one standard… .NET Standard: All in Visual Studio 2017“, Scott Hunter took a NorthWind class library (written for .NET Framework) and consumed that class in a .NET Core 2.0 web application.

for context, the NortWind application used XML and data readers – neither of which were available in .NET Standard 1.x

Worked Example

Watching the above linked Build talk is a great idea and it will provide you with a lot of information, but I’d recommend that you keep reading because I’m about to show you how to do it yourself.

or you could attempt to scrub your way through the talk, but here comes my example

The worked example we’re going to build is a little contrived and is really simplistic: we’re going to create a .NET Core console application which will generate a new password. We could write a library to do the password generation for us, but that wouldn’t be as interesting

I mean, it’s interesting, but not relevant to this article

We’re going to use a NuGet package which targets .NET Standard 4.5 called PasswordGenerator which was build by Paul Seal of codeshare.co.uk. This PasswordGenerator package uses the OWASP password complexity recommendations so our generated password will be a strong one with high enough entropy that we could use it in most external web applications.

if you’ve not heard of OWASP, then you owe it to yourself to go read through their recommendations for application security.

Consuming a .NET Framework NuGet package with a .NET Core application is extremely simple as you’ll see, but was previously unavailable to us .NET Core developers.

Ah, the magic of the .NET Standard

Creating a New Console Application

We’re going to build this application using the terminal and VS Code, only because it’s quicker and easier to actually use the terminal than it is to use a full IDE like Visual Studio (either for Windows or Mac), as we’re going to create a very simple application.

The first thing we need to do is ensure that we’ve installed .NET Core 2.0 preview 1, so open up the terminal and ask .NET Core which version of the SDK we have installed:

dotnet --version

which should return with a string similar to the following:

2.0.0-preview1-005977

if you have an earlier version installed, then you should be able to get the installer for the preview from here

Now we need to create a directory for the application (I’ll use PasswordGeneratorCore, but you can use whatever you wish):

mkdir PasswordGeneratorCore
cd PasswordGeneratorCore

and we want to create a console application in that directory:

dotnet new console

Adding a NuGet Package Reference

Now that we’ve created our console application, we need to add a reference to the external NuGet package. But first, let’s open the directory with VS Code as it’s easier than using nano/vim/emacs

I’m about to get a LOT of flack for that comment, but it’s my opinion

PasswordGeneratorCore in VS Code
The code base is pretty small and wont, really, get a lot bigger

Opening the PasswordGeneratorCore.csproj file, we’ll get proof that our application targets netcoreapp2.0 and we’ll see the tidier .NET Core 2.0 csproj file:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>

What we want to do is insert a reference to the PasswordGenerator NuGet package. To do that, add the highlighted lines to the csproj file:

<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="PasswordGenerator" version="1.1.2" Version="1.1.2" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>

Now that we’ve added a reference to our external NuGet package, we want to go and restore our packages in the terminal:

dotnet restore

VS Code will ask if you want to do it too, either way is fine.

which should return something similar to the following:

Restoring packages for /PasswordGeneratorCore/PasswordGeneratorCore.csproj...
Installing PasswordGenerator 1.1.2.
Lock file has not changed. Skipping lock file write. Path: /PasswordGeneratorCore/obj/project.assets.json
Restore completed in 2.03 sec for /PasswordGeneratorCore/PasswordGeneratorCore.csproj.
NuGet Config files used:
/.nuget/NuGet/NuGet.Config
Feeds used:
https://api.nuget.org/v3/index.json
/.dotnet/NuGetFallbackFolder
Installed:
1 package(s) to /PasswordGeneratorCore/PasswordGeneratorCore.csproj

I’ve altered the paths to make them more relevant, so yours won’t match exactly.

There’s nothing new here, except that we’re pulling the .NET Framework NuGet package and .NET Core 2.0 preview 1 is accepting that .NET Framework NuGet package.

If we’d have attempted to restore this package on an earlier version of .NET Core, we’ve had received an errors like the following:

Restoring packages for /PasswordGeneratorCore/PasswordGeneratorCore.csproj...
Installing PasswordGenerator 1.1.2.
/usr/share/dotnet/sdk/1.0.3/NuGet.targets(97,5): error : Unable to resolve 'Microsoft.NETCore.App (>= 2.0.0)' for '.NETCoreApp,Version=v2.0'. [/PasswordGeneratorCore/PasswordGeneratorCore.csproj]
Generating MSBuild file /PasswordGeneratorCore/obj/PasswordGeneratorCore.csproj.nuget.g.props.
Generating MSBuild file /PasswordGeneratorCore/obj/PasswordGeneratorCore.csproj.nuget.g.targets.
Writing lock file to disk. Path: /PasswordGeneratorCore/obj/project.assets.json
Restore failed in 1.59 sec for /PasswordGeneratorCore/PasswordGeneratorCore.csproj.
Errors in /PasswordGeneratorCore/PasswordGeneratorCore.csproj
Unable to resolve 'Microsoft.NETCore.App (>= 2.0.0)' for '.NETCoreApp,Version=v2.0'.

which tells us that the installed version of .NET Core cannot build the NuGet package that we have referenced, as it’s a .NET Framework package (and versions of .NET Core before 2.0 couldn’t build and use .NET Framework packages).

Let’s Use The Package

Now that the hard part is over

and it wasn’t even really that hard, was it?

Let’s use the NuGet package in out code.

I’d recommend that you go and read the documentation for PasswordGenerator over on it’s GitHub repo before we continue. I’m not going to go into the ins and outs of the class, but it’ll be worth you looking into what it’s doing and how it’s doing it.

Anyway, open the program.cs file and paste the following code into it:

using System;
namespace PasswordGeneratorCore
{
class Program
{
static void Main(string[] args)
{
// Create an instance of the PasswordGenerator (which is a .NET Framework package)
var pwGen = new PasswordGenerator()
// use PasswordGenerator's Fluent Api to include the character options
.IncludeLowercase()
.IncludeNumeric()
.IncludeSpecial()
.IncludeUppercase();
// generate a password using the .NET Framework package
var newPassword = pwGen.Next();
Console.WriteLine($"Generated password is: {newPassword}");
}
}
}

The comments in the code should explain what we’re doing.

Now let’s build and run the application:

dotnet run
Generated password is: 0yQ*rNmO0mkoJcBn

We’ve just called a .NET Framework class library from .NET Core. How amazing is that! Let’s do it again:

dotnet run
Generated password is: 43WxmKY%HjMV!5OH

Fantastic! Let’s do it one more time

dotnet run
Generated password is: VCh6KS5w\u[email protected]

Amazing!

Conclusion

We created an incredibly simple .NET Core application which references a .NET Framework class library, creates an object instance from that class and calls a group of methods on that .NET Framework object.

This is great news for the future of .NET Core development, especially since it means that .NET Core 2.0 preview 1 supports a LOT of NuGet packages that are currently out there, without any modification required. In fact, during the “Three Runtimes, one standard… .NET Standard: All in Visual Studio 2017” talk, the two Scotts (Hunter and Hanselman) showed the following slide:

NET Standard 2.0 preview announce slide
Source: https://sec.ch9.ms/sessions/c1f9c808-82bc-480a-a930-b340097f6cc1/build/2017/B8001.pptx

Considering that .NET Core 1.x didn’t have native support for NuGet packages which weren’t written specifically for .NET Core, our choice of libraries has just expanded hugely.

The remaining ~30% of NuGet packages aren’t supported because they, presumably, make use of APIs that are still not contained in .NET Standard 2.0. One superb resource for checking the APIs covered by the different versions of the .NET Standard is apisof.net

at the time of writing, the TLS certificate for apisof.net is broken. However, it is a Microsoft tool and was originally announced by Immo Landwerth during his YouTube series on .NET Standard, so it can be trusted.

What’s on your wishlist for .NET Standard 2.1? Also, which .NET Framework libraries and NuGet packages are you looking forward to using in your .NET Core 2.0 applications?

Thanks

I just want to take a moment to thank my good friend Paul Seal of codeshare.co.uk for creating the PasswordGenerator NuGet package.

Related Posts

A .NET developer specialising in ASP.NET MVC websites and services, with a background in WinForms and Games Development.

When not programming using .NET, he is either learning about .NET Core (and usually building something cross platform with it), speaking Japanese to anyone who’ll listen, learning about languages, writing for his non-dev blog, or writing for a blog about video games (which he runs with his brother)

  • Pingback: 1 – NET Core and .NET Framework Working Together, Or: The Magic of .NET Standard()

  • Pingback: The week in .NET – On .NET with Brett Morrison, DateTime Extensions | .NET Blog()

  • Sin8a

    make ONE sdk to rule them all as a layer over everything else and create a converter app to convert current codes, libraries,apps into that sdk

    or SOMETHING OF THE SORT.. WE ARE TIRED OF YOUR backward INSANITIES..

    FORMAT AND REINSTALL!

    • I don’t think it’s as easy as that for Microsoft.

      They have a long history of having to include backward compatibility in their products, because of the nature of how Windows was marketed in the early 90s. I remember a .NET Rocks! episode from about 4 months ago where the hosts discussed the sheer amount of backwards compatibility is required for the Windows kernel (as an example).

      I think that we’re heading in the right direction, and that having had the developers at Microsoft who work on .NET re-write the C# compiler (now known as Roslyn) in C# (it was originally in C++) has helped a lot.

      The next few years of .NET Core development are going to be an exciting time, for sure.