Introducing .NET Standard For The Enterprise

Code reuse is near the top, if not at the top, of my priority list. In the .NET world, that can mean only one thing, .NET Standard. Until a few months ago, the chance to experiment with it for the enterprise had not yet presented itself to me. Now that I have had that chance, I like the ability to write a single library so it can be reused by a wide range of applications across many platforms. What was nice is I didn't have to change a whole lot from writing regular .NET Framework Class Libraries. There were only a few gotchas.

What I hope to accomplish with this series is to teach some of the tricky or difficult lessons I have learned writing NuGet packages and applications in .NET Standard. Before I start diving in too far, it is important to understand what is .NET standard and why now is the time to start writing libraries in it.

.NET Standard - A Primer

Over the past couple of years, I have had the chance to attend a number of conferences. During that time I kept hearing about .NET Core. It can run on a Mac; it can run on Linux, it powered Universal Windows Application (UWP) apps, the next generation of ASP.NET, ASP.NET Core ran on it, it can pilot a spaceship to Pluto.

Next to those presentations were more presentations about Xamarin. Imagine writing a mobile app in C#, but it could run on Windows, iOS, Mac, and Android. I don't have to learn Objective-C?!?! Sign me up!

And off in the corner is the .NET Framework which has been around since the early 2000s. These are the old ASP.NET Webforms applications, the new ASP.NET MVC and ASP.NET WebAPI applications, the Winforms and WPF applications. My best estimate is 95% of all .NET applications are written in .NET Framework.

In my mind's eye, this is how I picture the .NET landscape, each piece was siloed from the either. (Thank you Microsoft for visualizing it for me!)

Courtesy of Microsoft

But...the folks over at Microsoft are some smart cookies. They could see the problem happening and started working on the solution which was .NET standard.

Courtesy of Microsoft

In a nutshell, .NET Standard enables a developer to write a class library, but it could be used on any of those platforms. Pretty slick, huh?

But what about .NET Portable Class Libraries (PCL) I can hear you asking. That was the same promise we heard when PCL was introduced. Think of PCL as a Beta for .NET Standard. Microsoft learned from their mistakes.

From the MSDN Blog "Introducing .NET Standard"

Let’s contrast this with how Portable Class Libraries (PCL) work today. With PCLs, you select the platforms you want to run on and the tooling presents you with the resulting API set you can use. So while the tooling helps you to produce binaries that work on multiple platforms, it still forces you to think about different base class libraries. With .NET Standard, you have a single base class library. Everything in it will be supported across all .NET platforms — current ones as well as future ones. Another key aspect is that the API availability in .NET Standard is very predictable: higher version equals more APIs. With PCLs, that’s not necessarily the case: the set of available APIs is the result of the intersection between the selected platforms, which doesn’t always produce an API surface you can easily predict.

.NET Standard - Now Ready for Primetime

As anyone in the software development industry knows, first the platform is introduced, then come the tools, then the support libraries, and then it is time to start banging out some code.

Let's walk through the timeline a little bit. The article referenced above was published on September 26th, 2016. At that time the latest version of Visual Studio was Visual Studio 2015. For the moment I'm going to leave out Visual Studio Code, as that is a completely separate animal. .NET Core 1.0 shipped in late June of 2016. It was possible to write .NET Standard Libraries using Visual Studio 2015, but it didn't have that "Native Feel" to it. I can't place my finger on it, but most people know what I mean. The support felt bolted on. Like the first GIT plug-in for Visual Studio. Visual Studio 2017 had .NET Standard support from the get go. It is right there when you go to create a new class library project. Now you have a choice, Class Library (.NET Framework) or Class library (.NET Standard).

So the tooling has been updated, yay! But what about the support NuGet packages everyone uses? The RestSharps, Entity Frameworks, and Log4Nets of the world? Well, since the announcement it looks like the majority of the major NuGet packages have been upgraded to support .NET Standard. This is critical to adoption rate. Without those packages, developers are forced to write everything. In other words, they weren't just making the pasta; they were cutting and mashing the tomatoes as well. Don't get me wrong, if that is what you want to do in your personal projects or you are trying to write a low-level library, then, by all means, be on the cutting edge. But those packages prevent the reinvention of the wheel.

Having the updated NuGet packages and Visual Studio makes .NET Standard ready for adoption in the majority of enterprises. Before that, writing .NET Standard code was in the early adopter phase. The phase where those of us who love technology are writing in it at home on side projects. Or, doing some sort of proof of concept to show off at work. Now, it is in the early majority and in a short bit it will just be the, um, standard, and more and more people will be using it. This makes it a lot easier to sell to the decision makers it is time to start writing in .NET Standard.

What's Missing

Writing in .NET Standard has shown a light on some NuGet packages I have used for years that have been all but abandoned. The most shocking to me is RestSharp. At the time of this writing (July 23rd, 2017), if you go on the Github repo you will see the last major update was over two years ago, and there is a big Help Wanted sign. This is a NuGet package which has been downloaded millions upon millions of times.

The other one was Microsoft's Unity Container. Microsoft said in a post they were handing off the maintenance of Unity Container to the community with a fancy new GitHub repo. The last time the source code was updated in that repo was over a year ago.

It is a bit of a bummer those libraries are no longer being maintained. But the good news is there are plenty of replacement libraries out there which are being actively maintained. And, there is no law saying you have to stop using those libraries. You only have to start making the switch when you start writing .NET Standard applications and libraries which need Dependency Injection and the ability to connect to RESTful services. Which, come to think about, are pretty much what all applications these days are needing.

Finding the right use case

I started writing in .NET standard because the of application suite I am the architect for at work. It runs the whole gambit of application types, ASP.NET WebAPI 2, Xamarin, Console Applications, Azure Functions. As I said at the beginning of this post, high on my priority list is code reusability. If I have to write a function that formats a person's name to "Last Name, First Name Middle Initial" then I only want to have to do to write that function once. That way if the format changes to Last Name, Middle Initial First Name, then I only have to change a single library, and update a package, not go in and change the same line of code 56 times.

That is why the best use case, and the best chance to introduce .NET Standard into your enterprise, is through a NuGet package which happens to target .NET standard. If all the applications that use the NuGet package target .NET 4.6.2, great, the code will still work. But you are setting yourself up for the future. And with minimal impact to the application. The first library is always the hardest one as you learn the ropes, but after that writing, additional libraries is very easy to do.

In my next post in this series, I will walk you through creating your first .NET Standard Class Library and in later posts wrapping that in a NuGet package.