With .NET Core, applications can be deployed including the runtime, and the runtime can be used from the target system shared between different applications. Both of these options are possible. This article explains how you can create and use self-contained applications. By default, the runtime is shared. This article shows how to create self-contained applications that include the runtime.
Creating a Library
To make the sample application not too simple, I’m creating a library that will be used from the application.
Preview 2 of the .NET Core tools allow creating a library using the command line:
> dotnet new --type Lib
This command creates the file Library.cs and the project file project.json with a dependency to NETStandard.Library:
{ "version": "1.0.0-*", "buildOptions": { "debugType": "portable" }, "dependencies": {}, "frameworks": { "netstandard1.6": { "dependencies": { "NETStandard.Library": "1.6.0" } } } }
With this library, I’m just creating a simple Foo
method that will be invoked by the application. To build the library, first the NuGet packages are restored (dotnet restore), the binaries built (dontet build), and the NuGet package created (dotnet pack).
> dotnet restore > dotnet build > dotnet pack
After creating NuGet packages, I copy them to a local folder on the system, e.g. c:\LocalPackages to have it available for my applications.
Creating the Calling Application
The calling application is created with dotnet new.
> dotnet new --type Console
The NuGet package Library is referenced within the dependencies of the application:
{ "version": "1.0.0-*", "buildOptions": { "debugType": "portable", "emitEntryPoint": true }, "dependencies": {}, "frameworks": { "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0" }, "Library": "1.0.0" }, "imports": "dnxcore50" } } }
To the the NuGet package from the local packages folder, you can either change the default configuration for NuGet, or add a NuGet.config file to the project directory. Having a custom NuGet.config file in the directory of the project has the advantage to not get in conflict with other projects. This NuGet.config adds the c:/LocalPackages folder to the configured package sources.
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="My Libraries" value="c:/LocalPackages" /> </packageSources> </configuration>
With this configuration in place, the program can be built, and the application can be published.
> dotnet restore > dotnet build > dotnet publish
dotnet publish writes all the files needed for publish in a publish directory. With the current configuration in place, you can find libraries for the application and the library in this directory. For the runtime just the configuration file App.runtimeconfig.json is available that specifies the runtime options:
{ "runtimeOptions": { "framework": { "name": "Microsoft.NETCore.App", "version": "1.0.0" } } }
This application is a portable application. The runtime is shared between different applications, and it is portable across different platforms.
A portable application shares the runtime with other applications and can run on different platforms.
Creating a Self-Contained Application
Just a few small changes are needed to create a self-contained application. A self-contained application distributes the runtime with the application.
To create a self-contained application, you need to make these changes to project.json:
- The type from the Microsoft.NETCore.App dependencies needs to be removed
- The runtimes section needs to be added
{ "version": "1.0.0-*", "buildOptions": { "debugType": "portable", "emitEntryPoint": true }, "dependencies": {}, "frameworks": { "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0" }, "Library": "1.0.0" }, "imports": "dnxcore50" } }, "runtimes": { "win7-x64": {} } }
The default type value is platform – a configuration value for portable applications. The platform entry needs to be removed. Building the application without the platform setting results in compilation errors. The compilation error lists possible runtime targets from the machine you’re compiling. On windows, some examples of runtime targets on Windows are win10-x64, win81-x64, win8-x64, win7-x64. Adding win7-x64 allows to run the application on Windows 7 and later.
Publishing the application with the runtime target configured creates a subdirectory publish below the directory name of the runtime-target. In this directory you can find the binaries of the application including the runtime.
Configuring multiple runtimes in project.json, you can
Self-contained applications don’t need the runtime installed on the target system. The runtime is delivered with the application.
Previously to the release of .NET Core, it was also possible to create native binaries using .NET Core. This feature is currently available only with apps for the Universal Windows Platform (UWP). For all platforms, this feature will come back with an upcoming version of .NET Core – it is just not clear yet when this will be.
Summary
.NET Core applications allow sharing the runtime on a system – similar to how the .NET Framework was used – but also to deliver the runtime with the application. This new variant is knwon by the term self-contained applications. There’s no longer the need to restrict to the version of the runtime that is installed on the target system. Improvements of new runtime versions can be used by the application without the need to wait until the new runtime is deployed to the target system.
Sample code is available with the More Samples from my book Professional C# 6 and .NET Core 1.0.
Have fun with programming and learning!
Christian
More Information
More information about .NET Core is available in my new book and my workshops.
Professional C# 6 and .NET Core 1.0
Package delivery image from © Yudesign | Dreamstime.com Delivery drone
3 thoughts on “Self Contained .NET Core Applications”