The Future of .NET
Unless you've been living under a rock for the past 6 to 12 months, you can't have escaped the fact that .NET has and continues to undergo some pretty dramatic changes.
We've got "dotnet core", ".NET 4.8", "dotnet standard 1, 1.1, 2…" and now or very, very soon anyway ".NET 5", just what is a lowly poor helpless dot net developer supposed to do to make sense of all this?
About a year ago, I did a talk for a local MS based user group called "The .NET Ecosystem", little did I know it would be so well received by those that attended. It was meant to be a very high level "manager" focused session, but instead it turned out to be better suited at helping developers actually understand what Microsoft's future vision for the .NET platform was really about.
Fig1: The intro page from my previous slide deck
The main question I set out to answer was the one that most folks seemed to be asking, and that was "Just how many .NET platforms are there, and which one should I be using?"
SO how many platforms are there then?
Only 2, Yep that's right you heard me correctly, only 2, no more, no less.
There's ".NET" and "dotnet core", and that's all.
.NET is Microsoft's original software development framework. It was originally designed as the managed code version of the original Win32 sdk used by C/C++ and pre managed language developers to create software on the windows platform.
In true MS style, it had to be backwards compatible, but allow for an easy path to future technologies.
MS wanted to keep the existing development community, but didn't want to alienate them by causing lots of pain in re-training them, so .NET included features to allow them to still call the Windows API's that they were all familiar with but without having to use a really low level unmanaged language like C/C++.
They also wanted the language semantics to be fairly portable, which back then for Microsoft meant being portable from one MS platform to another, such as from the windows desktop, to the IIS Web server environment, or the windows service control manager environment in a windows server system.
Back then, portability to Linux, Mac and other NON windows platform was not even a conversation starter.
.NET grew in popularity and as MS had hoped, more and more developers moved from C/C++ to C# and a large amount of classic VB6 developers had moved to the Visual Basic .NET platform.
By the mid to late 2000's, .NET had coverage on the Web, on the desktop and even in the mobile space thanks to the addition of .NET 3.5 to the windows mobile range of operating systems.
Fig2: My HTC Running windows Mobile 6.1 with .NET 3.5 built in
.NET became the platform of choice for windows developers. With every new version, MS added more features, and allowed it to be used in more places, and getting a web site up and running using web-forms was simple for anyone who had previous experience writing desktop windows applications using win-forms. Your existing skills where usable anywhere .NET ran as long as it was on the windows platform.
Then something unexpected happened…
Mobile computing exploded onto the scene, and at around this time a bunch of clever people wrote a .NET runtime for Linux, called "MONO"
The cross platform revolution begins…
The development of "MONO" for non-windows platforms was a pivotal moment in the history of the .NET platform.
For the first time ever it was possible to take C# and to a lesser extent VB.NET applications and run them on a non-windows platform.
More specifically, MONO was designed in such a way that it would transparently re-direct all windows forms API calls to GTK+ (GTK is a windowing toolkit similar to win-forms for Linux & Unix like platforms) compatible calls, meaning that a win-forms application written to work on the windows desktop could mostly be ported directly over to a Linux desktop with very few, and often no code changes to make it run.
There were still a lot of things that couldn't work, especially image and drawing tasks using GDI & GDI+ but in time, compatibility libraries where developed which filled in these cracks.
For the first time in .NET's history Microsoft could no longer use .NET as a reason to tie developers to the windows platform.
Then MONO was ported to run on Android, and now all of a sudden, Microsoft had the .NET framework running on a mobile platform they didn't control, and one very much bigger than anything that Microsoft ever built.
Xamarin is born…
The first real attempt was Xamarin, the company that had formed around a commercial version and vision for MONO, and the porting of MONO to both the iOS and Android platforms. Xamarin was acquired by Microsoft in 2016, and went on to become an integral part of Visual Studio from then on, allowing Visual Studio to be used to create applications that would run on the companies then new Windows Phone, Android and iOS platforms using similar UI technologies to the then new WPF technologies used for desktop development.
This worked pretty well, and when coupled with web technologies such as ASP.NET MVC, and HTML/UI apps compiled to cross platform web-frame based apps, did indeed give .NET a good start into being cross platform, unfortunately there was a problem, well lots of problems to be exact.
A lot of the graphics capabilities in the .NET stack where still very much windows specific, .NET on the desktop had its own API's as did Xamarin, and let's not forget Microsoft's experiment with Silverlight in an attempt to make a .NET version of Flash, that had a graphics subsystem unlike anything MS had before and have since. Then there was the fragmentation.
Each platform had its own compiler, its own build system and its own way of doing things. The only thing that was really common to them all was the language used.
Then there was the ever marching forward of the NodeJS runtime. Node was a big threat to many traditional tech industries, not just MS. It was threat because it was portable and easy to deploy.
Around 2016 when all this was happening, even though we could deploy MONO on Linux systems, actually getting a .NET web app up and running on a non-Microsoft, non-Internet Information Server was still a huge challenge. If you wanted .NET web applications, you still needed windows server and IIS to run them.
Also by this point in time, Microsoft where starting to look towards a future running from the cloud, and being a cloud services provider, Office 365 had been doing well for a few years by this point, and MS where beginning to realise the future lay in an environment where the compute environment was for all wants and purposes, mostly virtual allowing people to spin up and use whatever technology stack they were most comfortable with.
And so dotnet core was born.
The month after MS acquired Xamarin, version 1.0 of dotnet core was announced. Based on C# only, core 1.0 was more of an experiment than anything else. MS knew they needed to get a version of .NET released that could compete head on with NodeJS, one that didn't require expensive tooling and could work just as well from a non-graphic command line as it could from a high colour bitmapped display with lots of expensive editing tools. Core 1.0 was released with an update for Visual Studio 2015 Update 3.
5 months later, after a very rocky start and some absurd decisions about things like project file formats, core 1.1 was introduced and then 10 months after that, and a few more "upsetting the apple cart" moments, version 2.0 was released.
From dotnet core 2.0 onwards, MS started to get things right. The terminology on the command line stabilised. The tooling used with the command line got better, the project file format was established and accepted, and Microsoft started to port across many of the full .NET API's that developers using the full .NET framework where used to.
Core 2.0 however contained a very big surprise that no one really expected, self-hosted web applications.
For the first time ever, it was possible to create an ASP.NET based MVC web application and host and run it without needing ANY extra servers or software. Much of this was thanks to the emerging "OWIN" standard, which was a layered standard defining how platform specific services should use a middleware based pipeline architecture to allow run-time vendors to provide the server base in their base libraries, while leaving the developer to freely define the actual service logic in any way they see fit. This was a big deal for Microsoft because they could now genuinely compete in the NodeJS space, with an easy to use, simple, dynamic command line tool that allowed you to write a source file, then simply run that source file and host it as a service all from the same single command line tool.
But now we're maintaining 3 platforms…
If any of you are doing your maths here, you'll realize that we now have, dotnet core, traditional .NET and Xamarin, oh and MONO is still a thing even if it's not an official Microsoft platform on Linux.
MONO at this time became a little more important, due to the rise in the hobby electronics and maker's community's, with small computing platforms such as the RaspberryPI.
Again, NodeJS here flourished, as did Python and many other scriptable languages. Microsoft had, had a play around with a few ideas in this space, but again it was MONO that rescued the day, allowing text based command line applications to be easily ported to these new micro platforms, by Mid 2018 dotnet core had reached a mature enough level to hit Core 2.0 and Core 2.1 (The latter being the LTS or Long Term Supported version) and Microsoft felt confident enough to announce that the full classic .NET platform would be retired and placed in a maintenance only mode.
One of the big reasons Microsoft felt that the time was right was thanks to the .NET Standard.
Many folks, think that ".NET Standard" is yet another version of the .NET runtime.
.NET Standard however is not. Instead, it's a set of standards that any .NET runtime/compiler system MUST implement if it is allowed to label itself as adhering to that standard.
In September 2019, dotnet core 3.0 was announced, and core 3.0 was the first dotnet core version to be labelled as ".NET Standard 2 compliant". This for the Microsoft world was a big deal because ".NET Standard 2" is essentially the same level of operability as the classic .NET desktop runtime.
.NET Standard essentially states that at different levels, the runtime MUST implement different API surfaces, and make them available for applications running in the language compiler to consume and use. If a runtime standard of for example 1.0 is advertised, then it is expected than any application that only uses features in standard 1.0 or below should be able to run on that platform, unmodified.
Microsoft started defining the .NET standard back round about when they first acquired Xamarin, and indeed some of the later versions of Xamarin where compliant to the early versions of the standard. What's more these days, the .NET standard is no longer managed by Microsoft, but by the .NET foundation, and ANY .NET developer, company of runtime implementer can apply to join the foundation and get a say in future of how .NET standard is developed.
As of the date I presented my talk on the future of .NET, this is what the .NET standard chart looked like:
Figure 3: The Dot Net Standards
Down the left is the platform name your looking for, then as you go to the right, you pick the version of that platform, the number (In blue) at the top of that column, tells you what the level of the standard is, that platform supports.
So, as figure 3 shows, if you write a piece of software that uses only compatible code, and no 3rd party dependencies, and that bit of code is written to run on ".NET 4.6", then it should be expected that the same code will also run on "dotnet core 1.0" unmodified.
Since Core 3.1, a whopping 80% of the original .NET framework API's have been implemented, and any applications targeting .NET Framework 4.6.1 should run without modification on core 3.1
One of the best things about .NET standard however, is that the standards are public. You can get all the information you need from the .NET foundation, but it's perfectly possible for anyone to write their own .NET framework, and if you adhere to the particular standard you choose, your platform should run any application targeted for that standard. With the most recent versions of dotnet core, everything is now open source, and MS themselves actively want people to fork the runtime and create their own versions to support different platforms, as a result we're now seeing runtimes such as "Open Silver", a platform that takes advantage of the tech developed by Blazor and allows old Silver light applications to continue to be used on modern browsers, and I've no doubt we'll see more like this as time goes by.
With .NET framework now officially retired, MS are pushing for new development work to be done using Core 3.0 or higher and officially as far as Microsoft are concerned where back to just 2 runtimes now, Xamarin and Core, but even Xamarin is scheduled to change in the future.
And so that brings us to the most recent version…
.NET 5 is actually dotnet core 4.0, but because Microsoft want to try and simplify the versioning, they have chosen to drop the "core" name for all future versions, and follow on from where 4.8 (The last of the classic framework versions) left off.
.NET 5 is more than just core however, from 5 onwards Microsoft will start to implement their future vision of one .NET platform for every use.
We've already seen big strides made in this arena, with things like Blazor targeting the new web assembly platform, allowing you to run .NET code directly in the browser, and the announcement that in the future there are going to be new UI API's for Xamarin that will bring Xamarin apps closer in line with the code used in core apps, and future investment in improving dotnet core on micro devices such as the Raspberry PI.
Since the introduction of .NET core we've also seen a unified programming model, one that uses the "StartUp" class to configure just about every application you work on, one that makes the boiler plate code for every platform no matter how diverse, the same, and one that makes it possible to write truly cross platform code.
There's also, been huge amounts spent on investment in Microsoft's Azure cloud platform, to provide API's for .NET, bringing in Machine Learning and AI, and allowing the manipulation of Big Data all from standard .NET applications.
Microsoft's vision of one development platform spanning all possible targets is slowly taking shape, it'll take time to fully get there, but where in for a very rosy future.