Understanding the New Cross-Platform .NET, part 2 (ASP.NET)

Understanding the New Cross-Platform .NET, part 2 (ASP.NET)

In the first of this four-part series, we took a high-level look at the new “.NET Core” from the perspective of Java developers and veterans of other modern platforms.  dot net foundation logoWe saw how .NET Core differs from both Mono and the legacy “.NET Framework“, in terms of openness, cross-platform support, and basic use cases.

Here we’ll take a deeper dive into the new open-source and cross-platform ASP.NET framework and build system.

ASP.NET versions 1 through 4.5

ASP.NET is Microsoft’s flagship framework for web applications.  It was first released around the time that the Java community was flocking to Apache Struts (I know, stay with me!).  Just as Struts represented an evolution away from JSP and raw servlets, ASP.NET was likewise a successor to 1990’s-style Microsoft web development (i.e. classic ASP).

Struts radically changed over the years, went through a full re-write, and today has been all but completely replaced by Spring or JEE.  Meanwhile, ASP.NET has marched on and consistently retained its brand name, but under the covers it too has undergone periodic revolutions.  Early on, WebForms tried to make web development more approachable to Windows desktop app developers, by imitating concepts from WinForms.  Today, ASP.NET 4.5 would be more familiar to Spring programmers.  ASP.NET MVC provides the standard model-view-controller pattern, Razor templates are a clean and elegant twist on JSP/JSTL, and the companion Entity Framework is an ORM resembling Hibernate or JPA.

In 2012, Microsoft began open-sourcing chunks of ASP.NET and related frameworks under the Apache license.  This process accelerated when the .NET Foundation came into being in 2014.  Most of ASP.NET 4.5 can be used across platforms via Mono, but when using Microsoft’s official .NET Framework implementation it remains Windows-specific.

ASP.NET vNext

Coinciding with the release of .NET Core, ASP.NET will also receive a cross-platform re-implementation.  This initiative combines ASP.NET v.5, ASP.NET MVC v.6, and other components together under the umbrella term “ASP.NET vNext“.

To be honest, I’m only just beginning to absorb what the changes in vNext will mean at the code level.  However, we can talk now about the new developer toolchain and how applications will be built.

It’s important to note that going forward, ASP.NET is not just for web applications!  It is the umbrella over all of the build tools used to create cross-platform applications with .NET Core.  In various blogs and online forums, I’ve seen .NET veterans scratch their heads over new project templates, including one for generating an “ASP.NET Console Application”.  Java developers might be less fazed by this, since Spring or JEE have always been used in non-web contexts.

.NET Version Manager (dnvm)

The “dnvm” tool is a utility for managing multiple .NET instances on a single machine.  For pure-Java developers, this concept might seem alien or even silly.  If you have say, Java 7 and Java 8 both installed on your workstation, then you would probably toggle between them simply by adjusting your PATH and/or JAVA_HOME environment variables.  You might not even do that much, but rather just let an IDE handle it for you.

However, users of dynamic languages such as Ruby or Python should feel right at home.  Those communities are accustomed to managing their dependencies at the global level (e.g. install a Ruby gem, and it’s present for every Ruby application on that machine).  That of course leads to dependency conflicts between multiple applications.  So we have utilities like Ruby’s “RVM“, Python’s “virtualenv“, etc… which allow multiple distinct profiles to co-exist.

.NET more closely resembles Java than it does Ruby or Python.  Dependencies (a.k.a. “assemblies”) are bundled at the per-application level.  However, there are such fundamental differences between the modular .NET Core and the monolithic .NET Framework or Mono, that the build tools must behave differently based on which one you’re using for a given build.  The “dnvm” utility therefore lets you install multiple types of .NET implementation onto your workstation, and quickly toggle between them.

Initially, “dnvm” was called “kvm”.  In fact, all of these build tools had a naming convention of starting with the letter “k” (don’t ask why!).  Around March 2015, they were all renamed to begin with the letters “d” or “dn” (as in “dot-net”).  Just something to be aware of, since half of the documentation out there right now still refers to the previous names.

.NET Development Utility (dnu)

The “dnu” tool is responsible for managing dependencies and performing builds.  Java developers will see it as a very simplified stand-in for Maven or Gradle.  JavaScript developers might see it as a mash-up of npm or bower, along with Grunt or Gulp or whichever task runner is popular this week.  Prior to the big rename in early 2015, “dnu” was called “kpm”.

To use “dnu”, a project must have a “project.json” file in its root directory.  The format of this file strongly resembles a Maven POM or Gradle build script.  Among other things, it declares the project’s dependencies (i.e. the assemblies and exact version numbers needed for the app to work).  These are imported through a system called NuGet, from private locations or a public repository similar to Maven Central.

.NET Execution Environment (dnx)

The DNX is an SDK containing all of the bits needed to build and run an application.  A Java developer can think of the relationship between the DNX and a .NET implementation as being roughly similar to that between the JDK and the JRE.

You can have multiple DNX instances on a single machine.  In fact, they are the artifacts that are actually installed and managed by “dnvm”.  A DNX includes some version of .NET (i.e. Core, full Framework, or Mono), along with the “dnu.exe” build tool that we just discussed, and a “dnx.exe” application runner.  This runner can execute any commands defined in a project’s “project.json” file (e.g. “web“, to run an ASP.NET project in a local dev server process).

When you build a project deliverable using “dnu publish“, its root level contains Windows batch files (or Linux / OS X bash scripts) for each command in “project.json“.  These batch files invoke “dnx.exe“, which is expected to be installed and in the PATH on the machine to which you deploy.

When you use .NET Core, you can tell “dnu publish” to copy the entire DNX into the deliverable, and the batch files will reference that embedded copy.  This way you will have an entirely self-contained deliverable, which will not need .NET to be present on the target machine at all.

ASP.NET generator for Yeoman

Yeoman is a Node.js-based utility for kickstarting software projects with default templates.  Among the hundreds of generator options available is one for ASP.NET projects.  With one command, this generator creates a basic “Hello World” project for a web application, console application, or a handful of other types.  You can then take it from there with your own code.

Strictly speaking, this “aspnet” Yeoman generator is not part of ASP.NET.  It’s not written or maintained by Microsoft.  In fact, as of this writing I notice that it doesn’t even work on non-Windows systems (on OS X it still references outdated command names like “kpm”).  This tool is totally optional… you can always kickstart new projects with Visual Studio wizards, or by simply copying from another project.  However, if you’re doing modern web development then you probably have Node.js on your workstation anyway, so this Yeoman generator might come in handy once everything reaches maturity.

Conclusion

ASP.NET is evolving from a web framework into a umbrella project encompassing a family of frameworks.  Within this includes the developer tooling for building cross-platform .NET applications in general.

In the next section, we’ll look at the IDE’s and other tools now available under the Visual Studio brand.