New blog, vNext and some Runt-ing

It's been a while since I last blogged (a year ago in fact). However, a lot of interesting things have happened lately, so I figured it was time to rediscover the pen. In the mean-time I've always wanted to change out WordPress for something else, I've just never found something I really liked. I'm still not entirely sold on this Ghost-thingy, but apparently all the cool kids are using it, so I figured I might as well hop on the proverbial bandwagon.

A big advantage of Ghost is that it uses markdown. Also, the theming seems simple, so I'll probably write my own theme eventually. On the flip-side it doesn't seem to have spell-checking, so my posts will probably be as error-filled as they can possibly be, hopefully I figure out how to deal with that later.

All in all though, Ghost seems slick and simple, and easy to play around with (at least with simple stuff, like adding syntax-highlighting). While spell-checking is a pain-point, it's apparently on a todo-list somewhere, so hopefully that will be fixed eventually. I also quite like the editor that is shipped alongside Ghost.

.NET

If any of you ever read any of my blog-posts on my old blog, you'll know that what I tend to write about is mostly web related. In general, my two main topics are .NET and JavaScript. While there is a lot to say about JavaScript (with ES6 being in the works, and awesome-sauce on the way), most of that has already been said by people speaking far better and louder than me (and hopefully with fewer spelling-errors). Also, if you ask me, even though there are stuff moving in the JavaScript world, if you take a look at the bleeding edge of the .NET world, it just accelerated to a whole new level. As most of you who are reading this probably already know, I'm talking about ASP.NET vNext (or just vNext as I tend to call it).

One of the problems with vNext is that people seem to confuse what is part of vNext, what the "K" runtime is, what's simply the new project system, and how all this fits together with old regular .NET code/projects, and there's a whole bunch of terms being used for stuff that probably shouldn't be termed that way. I'm not going to try to explain the entirety of vNext, that would be a huge task, end end up in a blog post the size of a book. However, I will shortly talk about how some of the things work, and fit together.

vNext

Before we start, let's all take a moment to appreciate the man that is David Fowler, and the vNext team which made all this awesome-sauce possible. In his name, the NuGet package shall henceforth be known as nupkegs. May they live long and prosper.


Now that we've got that out of our system, let's take a look at what vNext is all about. But first of all, let's talk a bit about how .NET works in general. As most .NET developers know, .NET runs on a virtual machine, similar to Java and Python (amongst many others). When I create a .NET program and run it, what actually happens is that the CLR is booted, it loads my program and then runs it. However, since Microsoft was really smart when building .NET they made this entirely transparent. This means that if I generate a .NET runnable program (.exe), and double click it, it will simply run. I don't have to know that it's actually being run by another program. If, however, you were to run a .NET application on linux using mono, you typically have to do mono application.exe to run it.

Note: Some setups on linux can also successfully run .NET applications "as if" they were native applications, for instance by double-clicking them or simply doing application.exe in the console.

Now let's talk a bit about "K", the new CLR bootstrapper. Imagine for a moment that the CLR on a windows machine is accessible as clr in any command-line, just as mono is if installed. In other words, to run my application.exe I can either do clr application.exe or mono application.exe. If I'm on windows, I'd want to use clr normally, whereas on linux I'd want mono, as that's the only runtime available. However, amongst what's new in the world of vNext is a new CLR that's called the "Cloud Optimized CLR" (or CoreCLR), in other words we have to choose which runtime we want. This is generally handled by the kvm or "K Version Manager", and there should be enough information about it online, so I'm not going to cover that, however, the point is that we would like to have a unified way of invoking .NET vNext applications. Enter "K", the CLR bootstrapper. K can be configured on a machine/user or process level on which CLR to use, and then one can start any vNext application by doing k start in the application folder.

Note: It's possible to use k outside of an application folder. K accepts arguments specifying which folder/project to run, but the normal use-case is generally to stand in a project folder and do k run. K can also generate batch/sh files so that you can get away with running mycommand instead of k run.

Project.json

One of the coolest features in vNext in my opinion is the new project system. Instead of using Name.csproj you have a project.json file in the project directory, and all .cs files are by default included in the compilation. Let me repeat that for you. You no longer need to list all the files that go into your compilation! Another awesome feature is support for something called "Shared sources", which makes it super-easy to share C# source-files between projects. You can even create NuGet packages with a shared source project, so other projects (by other developers) can use your shared sources. This is similar to how some NuGet packages today work by inserting C# files into your project, with the exception that the files aren't copied into your project any more. However, the most awesome feature of all (in my opinion) is the fact that the "unit of reference" has changed from being a single assembly to NuGet packages (or project references).

To explain how this is really awesome, let's imagine a sample application which we wanted to work on desktop and mobile (windows phone, android and iPhone).

Note: As of today, project.json doesn't support most of these target frameworks. This will come in time, and should not be hard to add.

To get started we create an empty directory which will be our project-directory, named simply Test. The project-name is inferred from the directory-name, so it will simply be named Test as well. The we add the following project.json:

{
  "version": "0.1-alpha",
  "authors": ["Alxandr"],
  "description": "Test project that does nothing",
  "dependencies": {},
  "configurations": {
    "net45": {}
  }
}

If I build this project I would get a single assembly made for .NET 4.5 (short name: net45). It will find all .cs files in the directory, and compile them into a single assembly, then it will make a NuGet package, automatically. The NuGet package will get it's meta-data (version, authors and description) from the project.json file.

But as said earlier, we wanted to build to multiple targets. The best way to previously do just that was with Portable Class Libraries. However, Portable Class Libraries operates on Least Common Denominator (meaning it only exposes anything that all the target frameworks supports), whereas the new project system works more like having multiple .csproj, one for each target, and just using linked sources. The advantage to the later is that you can still use types that exists in all target frameworks, but might not be exposed through PCL because they might exist in different namespaces or similar. And if worst comes to worst, you can always use #if-defs to have conditional compilation.

By default the new project system exposes the target framework being built as a define, meaning the following works by default:

using System;

public namespace Test  
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string hello = "Hello from " +
#if NET45
            ".NET Framework v4.5";
#else
            "Some other .NET Framework";
#endif
            Console.WriteLine(hello);
        }
    }
}

This would print out Hello from .NET Framework v4.5 if I compiled it and ran it. However, if I were to add another compilation target (say net40, it would print out Hello from Some other .NET Framework.

To add new compilation targets, all we have to do is add them to our project.json file, like this:

{
  "version": "0.1-alpha",
  "authors": ["Alxandr"],
  "description": "Test project that does nothing",
  "dependencies": {},
  "configurations": {
    "net45": {},
    "WindowsPhone": {},
    "MonoAndroid": {},
    "MonoTouch": {}
  }
}

Note: As said, support for these frameworks are not yet supported, as such, their names such as MonoAndroid might prove to be wrong.

If I were to recompile the project now, having only changed 3 lines in the project.json file, I would get 4 assemblies instead of just 1, and all of them would be packaged into a single NuGet package. This is really powerful as it allows me to quickly target multiple platforms without having to write Least Common Denominator code, or manually managing a bunch of linked files across multiple .csproj files.

References

As mentioned earlier, this new project format changes the "unit of reference". This is also in terms with how you auto-magically get a NuGet package from your builds. So if we for instance want to add a reference to the popular JSON.NET we simply edit the project.json file to to have the following dependencies:

{
  "dependencies": {
    "Newtonsoft.Json": "6.0.3"
  }
}

If you run kpm restore on the project, this will automatically pull down the NuGet package Newtonsoft.Json version 6.0.3 (note, it will search any NuGet feeds configured on the machine, or in NuGet.Config in the project/solution directory) and all of it's dependencies. The dependencies are referenced transitively, meaning that if you reference a package A that has a dependency on the package B, which in turn has a dependency on C, all of the packages will be referenced by your project, but only A will be listed as a dependency in the NuGet package.

If you add an empty version-number, you get a project reference instead of a package reference. So if you have a directory named Projects, and you have a project in Projects/P1 and Projects/P2 and you in Projects/P1/project.json add a dependency on "P2": "", the Projects/P2 project will be added as a reference to P1, and just like with NuGet packages, all dependencies of P2 is also added to P1.

An implication of this system is that the system doesn't really differentiate between project references and NuGet package references. What this enables is to override a package with sources locally. For instance, say that you're working on a MVC project, and (given that the entirety of vNext is in alpha) you find a bug in MVC. So, being the good OSS-citizen you are, you download MVC, fix the bug, and send a pull-request with the fix. However, given the universal rule that "Things Take Time", you don't want to wait for the fix to land in the NuGet repository to continue working on your project, so instead you simply inform the new project system that it can find MVC in whatever folder you put MVC, and it will use the sources instead of the NuGet package. And when the fix finally does arrive in the central repository, you can simply delete your local sources, and it will go back to using the NuGet package instead. This feature is also great for debugging, as it allows you to step through the MVC sources.

Important: If you like these features, and would like to see them for more than just ASP.NET projects, go to uservoice and give your votes.

Runt

Last, but not least, I'd like to talk a bit about my latest project, namely "Runt". Runt is a new code-editor, mainly targeted at C# vNext projects (for now at least), and it's still far from usable. It's built on vNext and Orion (Eclipse-team's web based editor). It consists of a server running on Asp.Net vNext (with the help of SignalR, Roslyn and some other libraries), and a client written using TypeScript, React and more. The result is quite amazing.

The syntax hignlighting is built using Roslyn, and is blazingly fast. It also generates warnings and errors as seen in the image below.

Runt

Amongst the features that's working in Runt as of today are the following:

  • C# Syntax highlighting.
  • Listing of project references in a reference-tree.
  • Highlighting of compiler errors and warnings.
  • Hover over anything and get information about what you're hovering over, just like in VS.

Amongs the features in developement, code completion (content assist) is the most prominent one. I can't say when it will be done though, as it's currently blocked by K and Roslyn. Runt is open-source and can be found here: Runt.