.NET Generic Host
The Worker Service templates create a .NET Generic Host, HostBuilder. The Generic Host can be used with other types of .NET applications, such as Console apps.
A host is an object that encapsulates an app's resources, such as:
- Dependency injection (DI)
- Logging
- Configuration
IHostedService
implementations
When a host starts, it calls IHostedService.StartAsync on each implementation of IHostedService registered in the service container's collection of hosted services. In a worker service app, all IHostedService
implementations that contain BackgroundService instances have their BackgroundService.ExecuteAsync methods called.
The main reason for including all of the app's interdependent resources in one object is lifetime management: control over app startup and graceful shutdown. This is achieved with the Microsoft.Extensions.Hosting NuGet package.
Set up a host
The host is typically configured, built, and run by code in the Program
class. The Main
method:
- Calls a CreateDefaultBuilder() method to create and configure a builder object.
- Calls Build() to create an IHost instance.
- Calls Run or RunAsync method on the host object.
The .NET Worker Service templates generate the following code to create a Generic Host:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
Default builder settings
The CreateDefaultBuilder method:
- Sets the content root to the path returned by GetCurrentDirectory().
- Loads host configuration from:
- Environment variables prefixed with
DOTNET_
. - Command-line arguments.
- Environment variables prefixed with
- Loads app configuration from:
- appsettings.json.
- appsettings.{Environment}.json.
- Secret Manager when the app runs in the
Development
environment. - Environment variables.
- Command-line arguments.
- Adds the following logging providers:
- Console
- Debug
- EventSource
- EventLog (only when running on Windows)
- Enables scope validation and dependency validation when the environment is
Development
.
The ConfigureServices
method exposes the ability to add services to the Microsoft.Extensions.DependencyInjection.IServiceCollection instance. Later, these services can be made available from dependency injection.
Framework-provided services
The following services are registered automatically:
IHostApplicationLifetime
Inject the IHostApplicationLifetime service into any class to handle post-startup and graceful shutdown tasks. Three properties on the interface are cancellation tokens used to register app start and app stop event handler methods. The interface also includes a StopApplication() method.
The following example is an IHostedService
implementation that registers IHostApplicationLifetime
events:
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace AppLifetime.Example
{
public class ExampleHostedService : IHostedService
{
private readonly ILogger _logger;
public ExampleHostedService(
ILogger<ExampleHostedService> logger,
IHostApplicationLifetime appLifetime)
{
_logger = logger;
appLifetime.ApplicationStarted.Register(OnStarted);
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("1. StartAsync has been called.");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("4. StopAsync has been called.");
return Task.CompletedTask;
}
private void OnStarted()
{
_logger.LogInformation("2. OnStarted has been called.");
}
private void OnStopping()
{
_logger.LogInformation("3. OnStopping has been called.");
}
private void OnStopped()
{
_logger.LogInformation("5. OnStopped has been called.");
}
}
}
The Worker Service template could be modified to add the ExampleHostedService
implementation:
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace AppLifetime.Example
{
class Program
{
static Task Main(string[] args) =>
CreateHostBuilder(args).Build().RunAsync();
static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((_, services) =>
services.AddHostedService<ExampleHostedService>());
}
}
The application would write the following sample output:
// Sample output:
// info: ExampleHostedService[0]
// 1. StartAsync has been called.
// info: ExampleHostedService[0]
// 2. OnStarted has been called.
// info: Microsoft.Hosting.Lifetime[0]
// Application started.Press Ctrl+C to shut down.
// info: Microsoft.Hosting.Lifetime[0]
// Hosting environment: Production
// info: Microsoft.Hosting.Lifetime[0]
// Content root path: ..\app-lifetime\bin\Debug\net5.0
// info: ExampleHostedService[0]
// 3. OnStopping has been called.
// info: Microsoft.Hosting.Lifetime[0]
// Application is shutting down...
// info: ExampleHostedService[0]
// 4. StopAsync has been called.
// info: ExampleHostedService[0]
// 5. OnStopped has been called.
IHostLifetime
The IHostLifetime implementation controls when the host starts and when it stops. The last implementation registered is used.
Microsoft.Extensions.Hosting.Internal.ConsoleLifetime
is the default IHostLifetime
implementation. ConsoleLifetime
:
- Listens for Ctrl+C, SIGINT, or SIGTERM and calls StopApplication to start the shutdown process.
- Unblocks extensions such as
RunAsync
andWaitForShutdownAsync
.
IHostEnvironment
Inject the IHostEnvironment service into a class to get information about the following settings:
- IHostEnvironment.ApplicationName
- IHostEnvironment.ContentRootFileProvider
- IHostEnvironment.ContentRootPath
- IHostEnvironment.EnvironmentName
Host configuration
Host configuration is used to configure properties of the IHostEnvironment implementation.
The host configuration is available in HostBuilderContext.Configuration within the ConfigureAppConfiguration method. When calling the ConfigureAppConfiguration
method, the HostBuilderContext
and IConfigurationBuilder
are passed into the configureDelegate
. The configureDelegate
is defined as an Action<HostBuilderContext, IConfigurationBuilder>
. The host builder context exposes the .Configuration
property, which is an instance of IConfiguration
. It represents the configuration built from the host, whereas the IConfigurationBuilder
is the builder object used to configure the app.
Tip
After ConfigureAppConfiguration
is called the HostBuilderContext.Configuration
is replaced with the app config.
To add host configuration, call ConfigureHostConfiguration on IHostBuilder
. ConfigureHostConfiguration
can be called multiple times with additive results. The host uses whichever option sets a value last on a given key.
The following example creates host configuration:
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
class Program
{
static async Task Main(string[] args)
{
using IHost host = CreateHostBuilder(args).Build();
// Application code should start here.
await host.RunAsync();
}
static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(configHost =>
{
configHost.SetBasePath(Directory.GetCurrentDirectory());
configHost.AddJsonFile("hostsettings.json", optional: true);
configHost.AddEnvironmentVariables(prefix: "PREFIX_");
configHost.AddCommandLine(args);
});
}
App configuration
App configuration is created by calling ConfigureAppConfiguration on IHostBuilder
. ConfigureAppConfiguration
can be called multiple times with additive results. The app uses whichever option sets a value last on a given key.
The configuration created by ConfigureAppConfiguration
is available in HostBuilderContext.Configuration for subsequent operations and as a service from DI. The host configuration is also added to the app configuration.
For more information, see Configuration in .NET.
See also
- Configuration in .NET
- ASP.NET Core Web Host
- Generic host bugs should be created in the github.com/dotnet/extensions repo