A Beginner’s Guide to .NET’s HostBuilder: Part 1 — Introduction and Setup

Sawyer Watts
3 min readOct 28, 2023

.NET’s HostBuilder is an extremely powerful framework to handle the plumbing of a .NET application. The objective of this series is to provide a beginner’s guide to using .NET’s HostBuilder. The framework can be a bit mystical, but there is a substantial amount of power to be had.

Update: I have created a .NET console template using the topics discussed throughout this series here.

The series

  1. Introduction and Setup
  2. Dependency injection
  3. Cancellation
  4. Configurations and Environments
  5. Logging and Serilog

Table of contents

Readers may need to refresh after clicking a section

Disclaimers

  • Warning! There will be opinions. The reader will know their use case and environment much better than I do, so take the opinions with a grain of salt.
  • I will be focusing on the HostBuilder for this series. The WebHostBuilder is a superset of this functionality and I will mention it at points, but most of the web-specific features are out of scope for this series. This is for two reasons. First, this series will be long enough as-is. Second, anecdotally, developers seem to know comparatively more about the web-specific features within the WebHostBuilder.
  • I predominantly write web APIs and console applications, so my experiences are biased towards those use cases (and biased away from long-running workers).
  • My apps are almost always redeployed when a configuration changes occurs, so I am not particularly knowledgeable at mid-process configuration updates.
  • For this series, I will be using Ubuntu and a Bash terminal to show non-editing operations. I will be sure to explain what is happening so readers can best follow along with their tooling of choice.

Creating the project

This series will use a console application as its example. This is because it is a general-purpose starting point and because the SDK does not have a console template that configures the HostBuilder .

First, create a worker project with root namespace HostBuilderDemo. I find it easier to downgrade this template than to upgrade the console template.

$ dotnet new worker -n HostBuilderDemo
The template "Worker Service" was created successfully.

Processing post-creation actions...
Restoring /home/sawyer/Code/HostBuilderDemo/HostBuilderDemo.csproj:
Determining projects to restore...
Restored /home/sawyer/Code/HostBuilderDemo/HostBuilderDemo.csproj (in 194 ms).
Restore succeeded.


$ cd HostBuilderDemo
$ tree -I 'obj|bin' # This will print the tree structure, ignore obj/ and bin/
.
├── appsettings.Development.json
├── appsettings.json
├── HostBuilderDemo.csproj
├── Program.cs
├── Properties
│ └── launchSettings.json
└── Worker.cs

1 directory, 6 files

Next, remove Worker.cs and make Driver.cs with the following content:

namespace HostBuilderDemo;

public class Driver
{
public Task RunAsync(
CancellationToken cancellationToken)
{
Console.WriteLine("Hello, internet!");
return Task.CompletedTask;
}
}

After that, update Program.cs to be this text:

using HostBuilderDemo;

IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// services.AddHostedService<Worker>(); // Deleting this line.
// Added the next line, which will be explained in the dependency
// injection article.
services.AddTransient<Driver>();
})
.Build();

// host.Run(); // Deleting this line.

// Adding these lines:
Driver d = host.Services.GetRequiredService<Driver>();
// `default` will later be replaced with the real cancellation token in the
// cancellation article.
await d.RunAsync(default);

The app runs with the following output:

$ dotnet run
Building...
Hello, internet!

It is worth noting that this app does not run the built host, the app just builds the host and retrieves things from it directly. For more on running the host directly, see the worker and webapi templates and their documentation.

Here is the main structure this series will be tweaking:

$ tree -I 'obj|bin'  # This will print the tree structure, ignore obj/ and bin/
.
├── appsettings.Development.json
├── appsettings.json
├── Driver.cs
├── HostBuilderDemo.csproj
├── Program.cs
└── Properties
└── launchSettings.json

1 directory, 6 files

--

--