How YOU can get started with .NET Core and C# in VS Code

Chris Noring - Jul 17 '19 - - Dev Community

Follow me on Twitter, happy to take your suggestions on topics or improvements /Chris

This article covers your first steps using .NET Core, the cross-platform version of .NET. We will be creating a solution, a library, a console app and also a test project. Of course, we will be taught how to execute our tests, all this from the terminal

.NET has been around since 2001 and a lot of developers have cut their teeth on using Visual Basic .NET or C# with Visual Studio. They were using Windows at the time. Times have changed, cross-platform is a must nowadays and .NET as well as Visual Studio exists on both Windows, Linux, and Mac.

In this article we will cover:

  • Installing .NET Core and some nice extensions like C#
  • Scaffold a solution
  • Add a class library and add it to the solution
  • Add a test project and run our tests
  • Add a Console program and use our library
  • Improve our IDE with vscode-solution-explorer extension

what commands we were taught and what to look at next like ASP, Docker, Cloud

Resources

 Install and Set up

The first thing you want to do is to install .NET Core. Head over to this page:

https://www.microsoft.com/net/download/core

Once it's installed you should have access to a command-line tool you can invoke in the terminal called dotnet. You can easily see what commands are available by typing:

dotnet --help
Enter fullscreen mode Exit fullscreen mode

Quite a few commands as you can see above. We will explore some of these commands for creating solutions and projects.

Because we will be working with C# and VS Code I recommend downloading VS Code

https://code.visualstudio.com/download

Once you got VS Code on your system go and install the C# extension. Type C#, it should look like so:

Good, now we are set up and ready code :)

Creating a solution

The first we will do is to create a solution. A solution is something we use to keep track of all related projects. As an old .NET developer you might be used to do this via Visual Studio but we will actually do this via the terminal.

We will take the following steps:

  1. Create a directory for our solution
  2. Invoke the command generating a solution

First things first, let's create a directory:

mkdir app
cd app
Enter fullscreen mode Exit fullscreen mode

You can name your directory anything you want, app was just an example.

Next, let's create a solution. We do this with the following command:

dotnet new sln
Enter fullscreen mode Exit fullscreen mode

sln is short for solution, this will generate a new solution. Because we are standing in the app directory this generates an app.sln file.

 Create a library

Next up we will generate a library. Now a library is not an executable program but more a set of files we include in other projects.

To create a library we will need to type the following in the terminal (we are still in the app directory):

dotnet new classlib -o library
Enter fullscreen mode Exit fullscreen mode

Above we can see that our general command is dotnet new, followed by the type, which in this case is classlib, then we use the flag -o and the last argument is the name of the project.

Let's have a look at what we got:

We see that the directory library was created. We also see that we got the file Class1.cs, the project file library.csproj and a directory obj. At this point, lets switch to VS Code and look at our files. Looking att Class1.cs, it looks like this:


// Class1.cs

using System;

namespace library
{
  public class Class1
  {
  }
}
Enter fullscreen mode Exit fullscreen mode

It doesn't do much but it's valid C# code.

Let's finish this section by adding to the solution:

dotnet sln add library/library.csproj
Enter fullscreen mode Exit fullscreen mode

This adds the following entry to app.sln:

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "library", "library\library.csproj", "{7F30581E-9BCD-46FB-B7A5-FC2A85DE1429}"
Enter fullscreen mode Exit fullscreen mode

For now, we are not going to spend so much time thinking about this other than we have a solution that knows about our library.

Updating our library

Ok, we need to add some code to our library project. We will do the following:

  1. Download a NuGet package from a NuGet repository
  2. Reference our NuGet package in our library code
  3. Build our code

Download and use a package from the NuGet repository

https://www.nuget.org/

Is a big (160k + libraries) repository where all NuGet libraries live. Anything that lives here can be downloaded by a simple command. For this part, we will grab a specific library called Newtonsoft.Json. This will allow us to parse JSON back and forth. To make this library part of our solution we can type:

dotnet add library package Newtonsoft.Json
Enter fullscreen mode Exit fullscreen mode

The above means we are adding the package Newtonsoft.Json to the project library. The command should be read like this:

dotnet add [what project to add it to] package [name of package at nuget.org]
Enter fullscreen mode Exit fullscreen mode

Sometimes you might be working on an existing project or you might have grabbed the latest changes. Regardless of which, you might be missing some packages that your project or solution needs to run properly. At that point, you can run the command

dotnet restore
Enter fullscreen mode Exit fullscreen mode

This will grab the packages specified as package references in your projects csproj file.

Update our library code

In your library project, change the file Class1.cs to Thing.cs and add the following code to it:

// Thing.cs

using static Newtonsoft.Json.JsonConvert;

namespace Library
{
  public class Thing
  {
    public int Get(int left, int right) =>
        DeserializeObject<int>($"{left + right}");
  }
}
Enter fullscreen mode Exit fullscreen mode

 Build

Next up we need to compile our code. This will, if successful, generate a so-called .dll file. This is the format used by .NET for libraries and stands for dynamic link library.

So let's compile our code with the command:

dotnet build
Enter fullscreen mode Exit fullscreen mode

As indicated in the above image, we get a library.dll

Success!

Creating a test library

Next up we will create a test project. All codes deserve some level of testing and what better way to start than having tests set up early on. To create a test project we need to type the following:

dotnet new xunit -o test-library
Enter fullscreen mode Exit fullscreen mode

This will create a test project of type xunit with the name test-library.

Adding references

Let's add our project to the solution file as well:

dotnet sln add test-library/test-library.csproj
Enter fullscreen mode Exit fullscreen mode

The idea here is to test functionality found in our project called library. For this to be possible we need to add a reference to library in our test-library project, like so:

dotnet add test-library/test-library.csproj reference library/library.csproj
Enter fullscreen mode Exit fullscreen mode

Writing a test

When we created our test-library we got a file called UnitTest1.cs created as well. Let's have a look at this file:


//UnitTest.cs

using System;
using Xunit;

namespace test_library
{
    public class UnitTest1
    {
        [Fact]
        public void Test1()
        {

        }
    }
}
Enter fullscreen mode Exit fullscreen mode

We use the decorator [Fact] to indicate that this is a test method that needs to be evaluated and ran. Let's add some code next to UnitTest.cs:


//UnitTest.cs

using Library;
using Xunit;

namespace TestApp
{
    public class LibraryTests
    {
        [Fact]
        public void TestThing() {
            Assert.NotEqual(42, new Thing().Get(19, 23));
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

 Running our test/s

We are now ready to run our test and inspect the outcome.

To run the tests, type:

dotnet test test-library/test-library.csproj
Enter fullscreen mode Exit fullscreen mode

We use the command dotnet test and the last argument is where to find the project file for the test project. So what do we get?

We can see from the above image that our test run failed. It clearly indicated [Fail]. Let's look at the WHY. Expected the result to be NOT 42. Hmm, let's check the implementation in Thing.cs in our library project:

public int Get(int left, int right) =>
        DeserializeObject<int>($"{left + right}");
Enter fullscreen mode Exit fullscreen mode

We cleary just take 2 input arguments and sum them up. What about the test in UnitTest1.cs?

public void TestThing()
{
  Assert.NotEqual(42, new Thing().Get(19, 23));
}
Enter fullscreen mode Exit fullscreen mode

19 + 23 to be NOT equal to 42. Wait a minute... It should be Equal. Let's change that:

public void TestThing()
{
  Assert.Equal(42, new Thing().Get(19, 23));
}
Enter fullscreen mode Exit fullscreen mode

and let's rerun the test:

dotnet test test-library/test-library.csproj
Enter fullscreen mode Exit fullscreen mode

Let's inspect the results and....

This time around the tests is succeeding.

Success! :)

Console app

Next thing we are going to do is to create a Console App. Why do you ask? Well, we want to show the whole idea of creating a reusable library that we can drop in anywhere, from test projects to console projects.

Let's generate our console project like so:

dotnet new console -o console-app
Enter fullscreen mode Exit fullscreen mode

This gives us a runnable project with a file Program.cs that serves as the entry point. Technically the entry point is a method called Main():


// Program.cs

using System;

namespace console_app
{
  class Program
  {
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Let's add this project to the solution file, like so:

dotnet sln add console-app/console-app.csproj
Enter fullscreen mode Exit fullscreen mode

Adding and using our library project

Next order of business is to start using our library project and make it part of our console-app project. So we add the dependency like so:

dotnet add console-app/console-app.csproj reference library/library.csproj
Enter fullscreen mode Exit fullscreen mode

Read the above as:

dotnet add [target project] reference [destination project]
Enter fullscreen mode Exit fullscreen mode

Next up we need to change the code of our Program.cs file to the following:


// Program.cs

using System;
using Library;

namespace console_app
{
  class Program
  {
    static void Main(string[] args)
    {
        Console.WriteLine($"The answer is {new Thing().Get(19, 23)}");
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Let's run the app next

dotnet run -p console-app/console-app.csproj
Enter fullscreen mode Exit fullscreen mode

We got ourselves a running app, using the code from the library project.

Awesome :)

 Debugging

Debugging. That's one of the great things about using Visual Studio. It was and is outstanding. Personally, I think it's second to none, so what's the situation in VS Code?

Well, let's see how we debug and then reflect on how well it does it.

Now VS Code will ask you for adding a needed resource for debugging if you open a solution missing it. So how do I know what's missing? Well you should have a .vscode directory looking like this:

That's it?

Well, you might try to select Debug/Start Debugging from the menu and you will notice it's running the test-library if you look at the end of the debug window

Now, you probably want to change that to actually run the console-app project when debugging. To make that happen we need to go into launch.json under the directory .vscode. Find the entry looking something like this:

{
  "name": ".NET Core Launch (console)",
  "type": "coreclr",
  "request": "launch",
  "preLaunchTask": "build",
  // If you have changed target frameworks, make sure to update the program path.
  "program": "${workspaceFolder}/test-library/bin/Debug/netcoreapp2.2/test-library.dll",
  "args": [],
  "cwd": "${workspaceFolder}/test-library",
  // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
  "console": "internalConsole",
  "stopAtEntry": false
}
Enter fullscreen mode Exit fullscreen mode

We need to change the property "program" to point to our console app and also the "cwd".

It should now look like the below in launch.json

Then select menu option Debugging/Start Debugging and we should see the below

There we have it, boys and girls, working debugging :)

So, the experience, well the first thing that happened was that I just noticed that when I changed the code in Program.cs my breakpoint was not hit properly. This had an explanation. Looking at our entry in launch.json we see there is a property "preLaunchTask": "build" that points out a task that should run before our debug. This task resides in tasks.json. Heading over to that file we noticed that it looked like this:

{
  "label": "build",
  "command": "dotnet",
  "type": "process",
  "args": [
      "build",
      "${workspaceFolder}/test-library/test-library.csproj"
  ],
  "problemMatcher": "$tsc"
}
Enter fullscreen mode Exit fullscreen mode

YES, you are correct we weren't building the correct project before running the debug again. The way to fix this was to either run

dotnet build
Enter fullscreen mode Exit fullscreen mode

in the terminal OR, fix this task and have it point to our console-app, like so:

If you were to debug again everything works. Now you know a little bit more how things work in VS Code.

If I were to have an opinion here I would like to have this abstracted away from me as a user. I'd rather want a plugin doing this for me. At this point, I wish for a solution explorer, like the one I have in Visual Studio.

 Improve IDE

If you are like me with more 10+ years on the .NET platform, you are looking for ways to make this into Visual Studio as much as possible. You, of course, welcome new ways of doing things like using the terminal but it feels like you want a UI. Maybe I should use the actual Visual Studio then?

Well, there is a plugin that fixes this. It's called vscode-solution-explorer. If you install it your project will suddenly look like this:

and right-clicking on a project will give you a menu like this:

My spontaneous reaction is :)

This is not an official extension by Microsoft but it's very nice and well worth a try if you like me enjoy terminal commands but sometimes just want a UI.

Summary

Ok, let's try to sum this up. We have gotten quite the education on .NET Core. We were taught to use dotnet core to do everything from scaffolding different types of project to creating solutions, adding references, building our code to running tests. Quite versatile.

Lastly, we also showed a plugin that offers an alternate approach to all our terminal commands. Of course, under the hood, it's running our terminal commands, so there is definitely value to learn the ways of the CLI. :)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .