TQ
dev.com

Blog about software development

Subscribe to RSS

Programming C# on Ubuntu Linux

10 Nov 2016 - by 'Maurits van der Schee'

In this post we will be installing Microsoft .net Core SDK and Visual Studio Code on Ubuntu Linux and create high performance HTTP end-point in C# on which you can build a micro-service (or anything else).

Runtime installation

Follow instructions on https://www.microsoft.com/net/core#ubuntu:

sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
sudo apt-get update
sudo apt-get install dotnet-dev-1.0.0-preview2-003131

This instructions are for Ubuntu 16.04, but other operating systems are supported as well.

IDE installation

Now go to https://code.visualstudio.com/Download and download the ".deb" file. Install it by double-clicking or by running:

sudo dpkg -i ~/Downloads/code_1.7.1-1478180561_amd64.deb

Install the C# extension once you are started up. Note that if you already have Visual Studio Code, you may need to reinstall the extension after installing the runtime to properly enable it.

Project initialization

Now run the following to initialize your (first) C# project on Linux:

mkdir myProject
cd myProject
dotnet new

You can start Visual Studio code from the command line:

code

Now we are ready for some coding. There are two files:

using System;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

Program.cs (above) and project.json (below):

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        }
      },
      "imports": "dnxcore50"
    }
  }
}

Now we have a simple 'hello world' command-line application.

Hello world web server

In order to make this a web project we need to add Kestrel:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        },
        "Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
      },
      "imports": "dnxcore50"
    }
  }
}

Now that we added the dependency, we need to install the package:

dotnet restore

Great, now we need to add some code:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
            .UseUrls("http://localhost:8000/")
            .UseKestrel()
            .UseStartup<Startup>()
            .Build();

            host.Run();
        }
    }

    public class Startup
    {
        public void Configure(IApplicationBuilder app){
            app.Run(this.handler);
        }

        public Task handler(HttpContext context) {
           //Console.WriteLine("Received request");
           return context.Response.WriteAsync("Hello world");
        }
    }
}

As you can see this is pretty straight-forward code. You can run it using:

dotnet run

And then you may benchmark this using:

ab -c 10 -n 100000 http://localhost:8000/

And as you can see it performs well (20k reqs/sec on my machine).

Compiling to executable

I was trying to create an executable without dependencies, but I kept running into the error:

Can not find runtime target for framework '.NETCoreApp,Version=v1.0' compatible with one of the target runtimes: 'ubuntu.16.04-x64'.

Note that if you want to compile to 'exe' instead of 'dll' you need to change the lines:

"type": "platform",
"version": "1.0.1"

to:

//"type": "platform",
"version": "1.0.0"

Note that the type is removed and the version changed! And add to the bottom:

"runtimes": {
  "ubuntu.16.04-x64": {}
}

Now you need to rebuild:

dotnet restore

And then build a stand-alone executable including dependencies using:

dotnet build

Or if you also want to include the runtime in the build run:

dotnet publish

NB: This build and publish system has seen some recent adjustments, making it hard to Google this information.

Links

The following 3 articles can be used to learn more on this topic:

Enjoy programming C# on Linux!