In this article, we will see a sample program that uses .NET Core 3. We will review the process the developer will have to follow for producing native executable of his application. We will take a look at how to check the Visual Studio Installed Components, add the NuGet Repository which has the ILCompiler, add the dependency to your project, code your application and generate the native executable of the program.
Introduction: Compilation of a Managed Code?
The feature is not integrated in the SDK but provides to the C# developer an amazing way to produce machine executable from a .NET Core 3 original .csproj. From my point of view, this is a critical point when you want to distribute your software in a professional way (this is the way :). I discovered this feature in a stellar book (I didn’t forget to mention the source, for reference):
Developing multi-platform desktop applications with .NET Core 3 and Visual Studio 2019.
With this tool, the .NET Core 3 outmatches the concurrencies (Python, Node, Java) for the development of performance enhanced application (at last, C# almost reached the C++ performances level).
How It Works: The Principle
The .NET Core Runtime is used for generating AOT (Ahead of Time) image of the managed project. For building that, the pseudo compiler converts the MSIL program into C++ code and compiles the result for producing a native executable of the application (That’s why the C++ tools are required whatever the OS you are working on).
This complete process has been very well documented by one of its main developers (a Microsoft guy), Matt Warren.
For resuming, the compiler produces a real native executable, compared to an IL assembly which is compiled at run time to native code by the JIT (Just In Time compiler).
Fields of Application
The obvious benefits provided by using native executable are ridiculous performances improvement, the lack of framework to install.
The most adapted program for using the native format are mainly desktop applications (service, console or GUI) because the gain for local computing is quite noticeable for this type of application.
On the other hand, for web applications (Web app and API), the gains are not so obvious because of the kind of deployment they use. In a web server environment, most of the time, the framework is already installed on the machine and the use of a native executable is less manifest.
Sample Program
The sample program uses .NET Core 3. Let's review the process the developer will have to follow for making the jump in producing native executable of his application.
1. Check the Visual Studio Installed Components
Added to the required .NET Core 3 framework (and all the components required for the development with this framework), the ILCompiler required the setup of the C++ desktop feature.
Here is the C++ feature you have to install on Visual Studio:
2. Add the NuGet Repository which has the ILCompiler
A dedicated NuGet repository contains the Microsoft.Dotnet.ILCompiler
dependency required for the compilation of your program into real native executable.
This repository URL is:
https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json.
You have to add it to your NuGet source repos, if you use Visual Studio, you have to add it as described in picture 1 below.
Picture 1
3. Add the Dependency to Your Project
You can add Microsoft.Dotnet.ILCompiler
, by selecting it in the list of the available packages list as described in picture 2. Do not forget to check the box “Include prerelease” (because the package is still labelled “alpha” version).
Picture 2
4. Code Your Application
The sample console application does a factorial calculation with display of every rank (each step of the calculation) and displays the final result in red (groovy!).
Here is the source code:
using System;
namespace Net3Factorial
{
class Program
{
static long Factorial(int x)
{
long result = 1;
Console.ForegroundColor = ConsoleColor.Blue;
for (int i = 1; i <= x; i++)
{
result = result * i;
Console.WriteLine("Step {0}: {1}", i, result);
}
return result;
}
static void Main(string[] args)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Green;
Console.Clear();
Console.WriteLine("Enter the Integer for the factorial calculation:");
int num = Convert.ToInt32(Console.ReadLine());
long f = Factorial(num);
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("The Factorial of {0} is: {1}\n", num, f);
}
}
}
5. Generate the Native Executable of the Program
Once your project has been debugged and tested, you now want to produce the native executable of your application. The .csproj file has to include the target platform for the generation of the native executable, the runtime identifier (rid).
<runtimeidentifier>win-x64</runtimeidentifier>
If you use Visual Studio 2019, you can use the “Publish” command (context menu on the project item) for producing the native executable as shown in picture 3.
Picture 3
You can also use the CLI command "dotnet publish
" if you prefer the command line.
Conclusion
The generation of a native executable is a significant advantage for .NET Core 3, you benefit from the high productivity of C# and the performances are almost as good as the ones you could achieve using classic C++.
The ILCompiler
library can be used on Windows as described in this article, but on Linux and Mac OS X as well.
History
- 16th March, 2020: Initial version