.NET Core Tooling – What Are Your Options?

Tooling Header Image

Today’s header image was created by Barn Images, the original source for the image is available here

Note: While I was writing this article (like, a day before I published it), version 1.1 of .NET Core had moved away from the project.json format to using the csproj format. This means some of the examples here will be slightly out of date, but the core concepts remain the same.

Thus far in our journey whenever we’ve built anything together, we’ve always started with the terminal or command prompt.

That is with the exception of my MVC post, where I quickly ran through how to create it with Visual Studio towards the end.

I thought what I’d do this week is show you the different tools that you can use to create and maintain your .NET Core applications, and how you might use them.

dotnet new

We’re going to start with the terminal. Mainly we’re doing this because it can be harder to maintain a .NET Core application from here, because you have to manage EVERYTHING the source files yourself.

You’ll see an easier way to do this, in a moment.

Creating a Project

To create a project using the terminal, you’ll need to cd into a directory where your source files will be stored. In my example I used a directory called helloWorld. So the structure looked like this:

helloWorld dotnet new directory
This screenshot was created after running the commands in the next step

In the above screen shot, I’ve created a directory called helloWorld, then a subdirectory called src. After changing to the src directory, I ran the following command, which generated the two files.

dotnet new
view raw dotnet-shell.sh hosted with ❤ by GitHub

Here is exactly where we’ll start, because it’s the easiest command to run. Hopefully it’s super easy to understand too. We’re asking dotnet to create a new project. Running this command will produce two files in the directory where you run it:

  • project.json
  • program.cs

That’s it. Pretty simple eh?

If you take a look at program.cs, you’ll find a very familiar program listing:

using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
view raw dotnet-program.cs hosted with ❤ by GitHub

That’s right, Hello, World is the default listing for a new .NET Core application when you use the CLI.

Different Types of Project

The first thing we’re going to do is learn about the different projects we can create from the terminal. To do that, run this command:

dotnet new --help
view raw dotnet-shell.sh hosted with ❤ by GitHub

Which should return something like this:

.NET Initializer
Usage: dotnet new [options]
Options:
-h|--help Show help information
-l|--lang <LANGUAGE> Language of project [C#|F#]
-t|--type <TYPE> Type of project
yo aspnet
view raw dotnet-shell.sh hosted with ❤ by GitHub

So the different switches tell dotnet’s CLI which kind of project you would like to generate. The Language switch (‘-l’) should be self explanatory, but the type switch (‘-t’) is where the real fun is. You can supply one of these arguments, and dotnet will template a project for you:

  • console – This creates a Console Application, and is the default when a type is not supplied

  • web – This creates the default MVC application

  • lib – This creates an empty class library

  • uxinttest – This creates a unit test library

I’ve written about creating Console, MVC, Class Library and Unit Test applications in this way before.

Adding Files

There’s a few ways that you can do this, the easiest being in your file manager.

Explorer on Windows, Finder on macOS, or whatever you use on your Linux distro – might be nautilus if you’re running an Ubuntu.

It should just be a case of File > New, giving it a name and hitting return.

Dependent entirely on your file explorer of course.

You can also do this via the terminal, which is pretty neat.

touch new-file.cs
view raw dotnet-shell.sh hosted with ❤ by GitHub

This will tell your OS to create a new file for you, with the name ‘new-file.cs’

Editing Files

Since we’re working entirely in the terminal, we’re not going to be using an IDE. This means that you can edit your project files in whatever text editor you like.

I like to use Notepad++ (for Windows) when I can’t use an IDE, but feel free to use whatever you want.

Because we’re probably using a text editor (rather than an IDE), we’re not going to have IntelliSense, CodeLense or a debugger that we can run with a single button click.

This can prove tricky, as you might have to keep switching into and out of files as your program starts to get more complex, and you start adding more and more features.

Building, Running and Debugging

Building from the terminal is dead easy:

dotnet build
view raw dotnet-shell.sh hosted with ❤ by GitHub

This will tell dotnet to fire up Roslyn (the .NET compiler) and build your application. Depending on when you last restored your packages, you might get something like this in the terminal:

log : Lock file has not changed. Skipping lock file write. Path: /Your/Directory/Here/project.lock.json
log : /Your/Directory/Here/project.json
log : Restore completed in 1208ms.
view raw dotnet-shell.sh hosted with ❤ by GitHub

Either way, the output of the build command will look something like this:

Project HelloWorld (.NETCoreApp,Version=v1.0) will be compiled because expected outputs are missing
Compiling HelloWorld for .NETCoreApp,Version=v1.0
Compilation succeeded.
0 Warning(s)
0 Error(s)
Time elapsed 00:00:01.7556973
view raw dotnet-shell.sh hosted with ❤ by GitHub

Assuming that you get no compilation errors, of course.

Running is also quite easy:

dotnet run
view raw dotnet-shell.sh hosted with ❤ by GitHub

Assuming that the build process completed ok, your compiled application will be loaded and run by the .NET Core runtime.

But for debugging, there’s not much. At least, nothing other than running the application and watching it fall over that is. Thankfully, the .NET Core runtime is quite helpful in that any runtime errors or exceptions that cause your application to crash out completely will be dumped to the terminal

Exception thrown: 'System.NullReferenceException' in dwCheckApi.dll
Loaded '/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.2/System.Diagnostics.StackTrace.dll'. Cannot find or open the symbol file.
Loaded '/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.2/System.Reflection.Metadata.dll'. Cannot find or open the symbol file.
Loaded '/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.2/System.IO.MemoryMappedFiles.dll'. Cannot find or open the symbol file.
Loaded '/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.2/System.IO.UnmanagedMemoryStream.dll'. Cannot find or open the symbol file.
view raw dotnet-shell.sh hosted with ❤ by GitHub

What’s happened here is the infamous null reference exception. What’s also happened is that my system can’t find the files required to open and parse the null reference exception, so I have no way of knowing what actually caused it.

I actually forced one of my applications to throw the null ref and removed the files required to parse the exception, so I know exactly what happened and why.

Conclusion

It’s not that difficult to create and maintain small .NET Core applications from the terminal only, but as the application grows so will the complexity of the build errors, debugging isn’t so easy either.

There are a bunch of other options that will make it all so much easier. Let’s take a look at yeoman and Visual Studio Code.

yeoman, aspnet and Visual Studio Code

Here is where we’re going to start using IDEs. For this section, we’re going to Use Visual Studio Code as our IDE. It’s free, simple to use, fast, and extensible (there are thousands of plugins for it already).

If you haven’t already installed Visual Studio Code, then go take a look at this post for instructions on how to do that.

The link points directly at the relevant section too.

We’re also going to need to install the Yeoman generator engine and the aspnet template for it. You can do that by following the instructions on this page from the official .NET Core documentation.

Creating a Project

Creating a .NET Core project with the aspnet yeoman generator is super simple:

yo aspnet
view raw dotnet-shell.sh hosted with ❤ by GitHub

This will fire up the yeoman generator, and present you with a window similar to this one:

Yoeman Generator Screen
The yeoman generator is constantly being updated, so it may not look exactly like this.

Creating a project is simply a case of following the on-screen prompts (selecting a type, selecting any options, providing a name). Once you’ve done that, the generator will go ahead and take care of creating the basic files for you.

In my example app that I’m building, I chose Console Application and named it helloWorld.

Seem familiar?

Once your project has been created, open up Visual Studio Code, head to the File menu and chose Open.

Visual Studio Code Open
Clicking here will allow you to pick a directory

Then chose the directory with your project in, and it should load everything it needs.

Visual Studio Code with a Project Loaded
The left hand bar shows the directory structure of your project

And we’re ready to start coding.

Adding Files

Adding a file to a project loaded into Visual Studio Code is quite simple. There are a range of buttons at the head of the Explorer tab (just under your project name)

Visual Studio Code File Buttons
Left to right these are:
New File, New Folder, Refresh Listing and Collapse All

To add a new file, you just click on the New File button and give it a name.

The default location for a new file is context specific. So, if you were looking inside the .vscode folder, then clicking on the New File button will place a file there.

Visual Studio Code Added Some Files
I’ve added a bunch of files to my project

Using the New File button, it took me about 30 seconds to add the new files in this screen shot.

Editing Files

To edit a file, you just need to click on it in the left hand nav. Visual Studio Code will open an editor for it and show you the contents of the file.

Visual Studio Code Editing A File
Here I’ve opened the program.cs file

As you can see, I’ve opened my program.cs file and I can start editing it.

One cool feature of Visual Studio Code over using the terminal and text editors is that I can see where my program can be optimised. Lines 2, 3 and 4 of my program.cs have green squiggles. Placing the caret on one of them and looking next to the line number will reveal a light bulb, and when you click it:

Visual Studio Code Remove Unecessary Usings
The only useful option here is Remove Unnecessary Usings

If you choose Remove Unecessary Usings, then lines 2, 3 and 4 will be deleted. This will reduce the number of libraries that you app will need, in order to run.

Pretty cool, eh?

Building, Running and Debugging

All three of these options are dealt with in one place, the tabs on the far left of the window.

Visual Studio Code Tabs
From top to bottom, these are:
Explorer, Search, Git, Debug, and Extensions

Explorer (the top icon) is where we started and what listed our project’s files. Search allows us to search all of the files in the project (very useful for tracking down a particular line of code or variable).

The third option is what we want: Debug.

Visual Studio Code Debug Pane Not Running
Here’s the debug pane, without the debugger running

There’s a lot going on here, but lets just hit the green play button for now. There’s be a flurry of activity in the Output window (which should pop up from the bottom of the screen), and you’ll see something like this:

Visual Studio Code Debugger Running
I’ve put a breakpoint in, to pause the application

Here we can see a bunch of information. On the left we have Variables (this is analogous to the Locals tab in Visual Studio), Watch (this is the same as the Watch tab in Visual Studio) and the Call Stack.

The Variables tab displays all variables (and their values) that are in scope, as control passes to different methods, this list will be updated and will only contain the values specific to that scope.

You can add whatever variables you want to the Watch tab, and they’ll remain there throughout the life time of any debug sessions (regardless of whether they are in scope of not), and you can directly edit the value of any variables listed in the Watch tab. If the variable isn’t in scope, then it will be disabled but still visible.

The Call Stack retains a list of all method calls that we made to get to this point.

Along the bottom of the screen we have the debug window. Using this, we can directly interact with any variables that are within scope (altering their values, etc.). Another thing we can do is issue commands and call some methods.

Visual Studio Code Debug Console
Ha! There I am

Because the Debug Console expects expressions, it evaluated mine

Console.WriteLine(“I’m in the debug console now”)

Told me that it had no value

That’s a bit mean

Then ran the call and wrote to the console window.

Conclusion

Visual Studio Code is really great and is a competent IDE, with full fleshed out hooks into the .NET Core debugger. It’s what I use whenever I’m developing .NET Core stuff on my mac and (until this point) what I’ve used to write this blog post.

Visual Studio 2015/2017

Visual Studio is Microsoft’s premium (well, freemium I guess) IDE for all things .NET. But it’s so much more than that, as we’ll see.

And that’s not to mention the languages and frameworks which is supports, but I’m not going to go into them.

Way to tease, Jamie.

Anyway, you’ll need Visual Studio 2015 (with update 3) or the shiny new Visual Studio 2017 to create .NET Core applications.

Visual Studio 2017 was in Release Candidate as this post was written, so it was still very shiny new, and I haven’t had a chance to play with it yet.

The other options so far have been (for the most part) platform agnostic, so you could try them on a machine running macOS, Ubuntu Linux or Windows 10. This option is for Windows 10 users only, I’m afraid.

Unless you run something like Parallels or Bootcamp (on macOS), or a fantastic virtual machine, I suppose.

Creating a Project

Creating a .NET Core project in Visual Studio is a doddle.

doddle, noun – “a very easy task.”

In the File menu for Visual Studio, choose New then New Project (Ctrl+Shift+N is a nice shortcut for this), You should get a window that looks a little like this:

Visual Studio 2015 New .NET Core Window
I’m using Visual Studio 2015 with the dark theme, so it might look a little different on your machine.

Here we can see the different application options:

  • Class library
  • Console library
  • ASP.NET Core Web Application

I’m going to create a Console Application called HelloWorld.

Seems like there’s a pattern forming.

An interesting difference when creating a project using Visual Studio is that the files are laid out differently.

Visual Studio .NET Core Project Layout
We didn’t have an src directory when we used the other two options.
Adding Files

Adding a new file to the Visual Studio project is really easy.

But not as easy as it is in Visual Studio Code, I must say.

  • Right click the project you want the new file to be included in
  • Hover over Add
  • Click on New Item

Visual Studio Add New File Menu

A wizard will open and this will have a bunch of templates for your new file: select the file type that you want, give it a name and hit Add

Visual Studio Add New File Wizard
The available templates are based on the application type that you selected when creating the project.
Editing Files

Editing files is also really easy. All you need to do is find the file that you want to edit (it will be listed in the Solution Explorer, double click it, and Visual Studio will open an editor for that file.

Visual Studio .NET Core Project Layout
Here I’ve opened the Program.cs file

Save after editing, obviously.

Building, Running and Debugging

Building in Visual Studio is easy, either go to the Build menu and choose Build Solution, or hit Crtl+Shft+B.

Viola! A build!

Running is even easier.

Visual Studio Run Button
Click on the big green button, and everything will be built and run for you

Debugging, though. That’s where Visual Studio comes into it’s own and proves that it’s the top dog.

The first thing I’m going to do, for demo purposes is change the contents of program.cs. Here’s how the new one is going to read:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace HelloWorld
{
public class Program
{
public static void Main(string[] args)
{
var someValue = default(int);
var someBool = false;
if (args.Any())
{
Console.WriteLine("What?!");
return;
}
Console.WriteLine("Hello, World");
}
}
}

I’ve added a few variables (that will remain unused) and done a check on args (the arguments passed into my app from the terminal), based on the state of args I’m returning a different string then exiting.

Let’s fire this up, stick a break point on line 14 and see what happens.

Visual Studio Running With Debugger
Here is my altered HelloWorld app running with the debugger attached. Pretty cool, eh?

The debugging tools that we have here are immense. The Locals tab (at the bottom of the image) shows us all of the variables in local scope and their values. The Diagnostics tab tells us how much RAM and CPU we’re using. We can even use the Watch tab (collapsed at the bottom of the image) to keep an eye on the value of a variable as it’s passed around the system.

The Locals tab is strictly for local variables and it’s contents will be refreshed as we move from method to method. Whereas, the Watch tab will only be emptied as and when you tell it to. Once a variable in the Watch tab has gone out of scope, it will be disabled but will remain in the tab. Either of these tabs allow you to edit the values of the variables as we step through the code.

Conclusion

If you’re running Windows 10 (or can run Parallels/Bootcamp or a decent enough virtual machine), then Visual Studio is the IDE of choice. It has all the features of Visual Studio Code without the need to install extensions. Plus, it has a whole heap of features that I didn’t even go into.

When I’m using Windows, I tend to use Visual Studio over Visual Studio Code.

Although, I tend to use Visual Studio Code to edit Markdownwhen I’m running Windows.

Addendum

As I was writing this blog post, Microsoft announced that the release candidate for Visual Studio 2017 has support for .NET Core 1.1 with csproj.

This is just the release candidate (with the final release date being “early 2017”), but it’s worth trying out if you’re running Windows.

Oh, and according to this video by Immo Landswerth (less than 24 hours old at the time of publishing this article), Visual Studio 2017 will ship with .NET Core 1.2, which is quite exciting.

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 Retro Gaming (which he runs with his brother)