AspNetCore.Docs/aspnetcore/fundamentals/host/generic-host.md

24 KiB

title author description monikerRange ms.author ms.custom ms.date uid
.NET Generic Host guardrex Learn about ASP.NET Core's Generic Host, which is responsible for app startup and lifetime management. >= aspnetcore-2.1 riande mvc 11/28/2018 fundamentals/host/generic-host

.NET Generic Host

By Luke Latham

::: moniker range="<= aspnetcore-2.2"

ASP.NET Core apps configure and launch a host. The host is responsible for app startup and lifetime management.

This article covers the ASP.NET Core Generic Host (xref:Microsoft.Extensions.Hosting.HostBuilder), which is used for apps that don't process HTTP requests.

The purpose of Generic Host is to decouple the HTTP pipeline from the Web Host API to enable a wider array of host scenarios. Messaging, background tasks, and other non-HTTP workloads based on Generic Host benefit from cross-cutting capabilities, such as configuration, dependency injection (DI), and logging.

Generic Host is new in ASP.NET Core 2.1 and isn't suitable for web hosting scenarios. For web hosting scenarios, use the Web Host. Generic Host will replace Web Host in a future release and act as the primary host API in both HTTP and non-HTTP scenarios.

::: moniker-end

::: moniker range="> aspnetcore-2.2"

ASP.NET Core apps configure and launch a host. The host is responsible for app startup and lifetime management.

This article covers the .NET Core Generic Host (xref:Microsoft.Extensions.Hosting.HostBuilder).

Generic Host differs from Web Host in that it decouples the HTTP pipeline from the Web Host API to enable a wider array of host scenarios. Messaging, background tasks, and other non-HTTP workloads can use Generic Host and benefit from cross-cutting capabilities, such as configuration, dependency injection (DI), and logging.

Starting in ASP.NET Core 3.0, Generic Host is recommended for both HTTP and non-HTTP workloads. An HTTP server implementation, if included, runs as an implementation of xref:Microsoft.Extensions.Hosting.IHostedService. IHostedService is an interface that can be used for other workloads as well.

Web Host is no longer recommended for web apps but remains available for backward compatibility.

[!NOTE] This remainder of this article has not yet been updated for 3.0.

::: moniker-end

View or download sample code (how to download)

When running the sample app in Visual Studio Code, use an external or integrated terminal. Don't run the sample in an internalConsole.

To set the console in Visual Studio Code:

  1. Open the .vscode/launch.json file.
  2. In the .NET Core Launch (console) configuration, locate the console entry. Set the value to either externalTerminal or integratedTerminal.

Introduction

The Generic Host library is available in the xref:Microsoft.Extensions.Hosting namespace and provided by the Microsoft.Extensions.Hosting package. The Microsoft.Extensions.Hosting package is included in the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later).

xref:Microsoft.Extensions.Hosting.IHostedService is the entry point to code execution. Each IHostedService implementation is executed in the order of service registration in ConfigureServices. xref:Microsoft.Extensions.Hosting.IHostedService.StartAsync* is called on each IHostedService when the host starts, and xref:Microsoft.Extensions.Hosting.IHostedService.StopAsync* is called in reverse registration order when the host shuts down gracefully.

Set up a host

xref:Microsoft.Extensions.Hosting.IHostBuilder is the main component that libraries and apps use to initialize, build, and run the host:

[!code-csharp]

Options

xref:Microsoft.Extensions.Hosting.HostOptions configure options for the xref:Microsoft.Extensions.Hosting.IHost.

Shutdown timeout

xref:Microsoft.Extensions.Hosting.HostOptions.ShutdownTimeout* sets the timeout for xref:Microsoft.Extensions.Hosting.IHost.StopAsync*. The default value is five seconds.

The following option configuration in Program.Main increases the default five second shutdown timeout to 20 seconds:

var host = new HostBuilder()
    .ConfigureServices((hostContext, services) =>
    {
        services.Configure<HostOptions>(option =>
        {
            option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
        });
    })
    .Build();

Default services

The following services are registered during host initialization:

Host configuration

Host configuration is created by:

Extension methods

Application key (name)

The IHostingEnvironment.ApplicationName property is set from host configuration during host construction. To set the value explicitly, use the HostDefaults.ApplicationKey:

Key: applicationName
Type: string
Default: The name of the assembly containing the app's entry point.
Set using: HostBuilderContext.HostingEnvironment.ApplicationName
Environment variable: <PREFIX_>APPLICATIONNAME (<PREFIX_> is optional and user-defined)

Content root

This setting determines where the host begins searching for content files.

Key: contentRoot
Type: string
Default: Defaults to the folder where the app assembly resides.
Set using: UseContentRoot
Environment variable: <PREFIX_>CONTENTROOT (<PREFIX_> is optional and user-defined)

If the path doesn't exist, the host fails to start.

[!code-csharp]

Environment

Sets the app's environment.

Key: environment
Type: string
Default: Production
Set using: UseEnvironment
Environment variable: <PREFIX_>ENVIRONMENT (<PREFIX_> is optional and user-defined)

The environment can be set to any value. Framework-defined values include Development, Staging, and Production. Values aren't case sensitive.

[!code-csharp]

ConfigureHostConfiguration

ConfigureHostConfiguration uses an xref:Microsoft.Extensions.Configuration.IConfigurationBuilder to create an xref:Microsoft.Extensions.Configuration.IConfiguration for the host. The host configuration is used to initialize the xref:Microsoft.Extensions.Hosting.IHostingEnvironment for use in the app's build process.

ConfigureHostConfiguration can be called multiple times with additive results. The host uses whichever option sets a value last on a given key.

Host configuration automatically flows to app configuration (ConfigureAppConfiguration and the rest of the app).

No providers are included by default. You must explicitly specify whatever configuration providers the app requires in ConfigureHostConfiguration, including:

  • File configuration (for example, from a hostsettings.json file).
  • Environment variable configuration.
  • Command-line argument configuration.
  • Any other required configuration providers.

File configuration of the host is enabled by specifying the app's base path with SetBasePath followed by a call to one of the file configuration providers. The sample app uses a JSON file, hostsettings.json, and calls xref:Microsoft.Extensions.Configuration.JsonConfigurationExtensions.AddJsonFile* to consume the file's host configuration settings.

To add environment variable configuration of the host, call xref:Microsoft.Extensions.Configuration.EnvironmentVariablesExtensions.AddEnvironmentVariables* on the host builder. AddEnvironmentVariables accepts an optional user-defined prefix. The sample app uses a prefix of PREFIX_. The prefix is removed when the environment variables are read. When the sample app's host is configured, the environment variable value for PREFIX_ENVIRONMENT becomes the host configuration value for the environment key.

During development when using Visual Studio or running an app with dotnet run, environment variables may be set in the Properties/launchSettings.json file. In Visual Studio Code, environment variables may be set in the .vscode/launch.json file during development. For more information, see xref:fundamentals/environments.

Command-line configuration is added by calling xref:Microsoft.Extensions.Configuration.CommandLineConfigurationExtensions.AddCommandLine*. Command-line configuration is added last to permit command-line arguments to override configuration provided by the earlier configuration providers.

hostsettings.json:

[!code-csharp]

Additional configuration can be provided with the applicationName and contentRoot keys.

Example HostBuilder configuration using ConfigureHostConfiguration:

[!code-csharp]

ConfigureAppConfiguration

App configuration is created by calling xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureAppConfiguration* on the xref:Microsoft.Extensions.Hosting.IHostBuilder implementation. ConfigureAppConfiguration uses an xref:Microsoft.Extensions.Configuration.IConfigurationBuilder to create an xref:Microsoft.Extensions.Configuration.IConfiguration for the app. 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 at HostBuilderContext.Configuration for subsequent operations and in xref:Microsoft.Extensions.Hosting.IHost.Services*.

App configuration automatically receives host configuration provided by ConfigureHostConfiguration.

Example app configuration using ConfigureAppConfiguration:

[!code-csharp]

appsettings.json:

[!code-csharp]

appsettings.Development.json:

[!code-csharp]

appsettings.Production.json:

[!code-csharp]

To move settings files to the output directory, specify the settings files as MSBuild project items in the project file. The sample app moves its JSON app settings files and hostsettings.json with the following <Content> item:

<ItemGroup>
  <Content Include="**\*.json" Exclude="bin\**\*;obj\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

ConfigureServices

xref:Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.ConfigureServices* adds services to the app's dependency injection container. ConfigureServices can be called multiple times with additive results.

A hosted service is a class with background task logic that implements the xref:Microsoft.Extensions.Hosting.IHostedService interface. For more information, see xref:fundamentals/host/hosted-services.

The sample app uses the AddHostedService extension method to add a service for lifetime events, LifetimeEventsHostedService, and a timed background task, TimedHostedService, to the app:

[!code-csharp]

ConfigureLogging

xref:Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.ConfigureLogging* adds a delegate for configuring the provided xref:Microsoft.Extensions.Logging.ILoggingBuilder. ConfigureLogging may be called multiple times with additive results.

[!code-csharp]

UseConsoleLifetime

xref:Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.UseConsoleLifetime* listens for Ctrl+C/SIGINT or SIGTERM and calls xref:Microsoft.Extensions.Hosting.IApplicationLifetime.StopApplication* to start the shutdown process. UseConsoleLifetime unblocks extensions such as RunAsync and WaitForShutdownAsync. xref:Microsoft.Extensions.Hosting.Internal.ConsoleLifetime is pre-registered as the default lifetime implementation. The last lifetime registered is used.

[!code-csharp]

Container configuration

To support plugging in other containers, the host can accept an xref:Microsoft.Extensions.DependencyInjection.IServiceProviderFactory`1. Providing a factory isn't part of the DI container registration but is instead a host intrinsic used to create the concrete DI container. UseServiceProviderFactory(IServiceProviderFactory<TContainerBuilder>) overrides the default factory used to create the app's service provider.

Custom container configuration is managed by the xref:Microsoft.Extensions.Hosting.HostBuilder.ConfigureContainer* method. ConfigureContainer provides a strongly-typed experience for configuring the container on top of the underlying host API. ConfigureContainer can be called multiple times with additive results.

Create a service container for the app:

[!code-csharp]

Provide a service container factory:

[!code-csharp]

Use the factory and configure the custom service container for the app:

[!code-csharp]

Extensibility

Host extensibility is performed with extension methods on IHostBuilder. The following example shows how an extension method extends an IHostBuilder implementation with the TimedHostedService example demonstrated in xref:fundamentals/host/hosted-services.

var host = new HostBuilder()
    .UseHostedService<TimedHostedService>()
    .Build();

await host.StartAsync();

An app establishes the UseHostedService extension method to register the hosted service passed in T:

using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public static class Extensions
{
    public static IHostBuilder UseHostedService<T>(this IHostBuilder hostBuilder)
        where T : class, IHostedService, IDisposable
    {
        return hostBuilder.ConfigureServices(services =>
            services.AddHostedService<T>());
    }
}

Manage the host

The xref:Microsoft.Extensions.Hosting.IHost implementation is responsible for starting and stopping the IHostedService implementations that are registered in the service container.

Run

xref:Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run* runs the app and blocks the calling thread until the host is shut down:

public class Program
{
    public void Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        host.Run();
    }
}

RunAsync

xref:Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync* runs the app and returns a Task that completes when the cancellation token or shutdown is triggered:

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        await host.RunAsync();
    }
}

RunConsoleAsync

xref:Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.RunConsoleAsync* enables console support, builds and starts the host, and waits for Ctrl+C/SIGINT or SIGTERM to shut down.

public class Program
{
    public static async Task Main(string[] args)
    {
        var hostBuilder = new HostBuilder();

        await hostBuilder.RunConsoleAsync();
    }
}

Start and StopAsync

xref:Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Start* starts the host synchronously.

xref:Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.StopAsync* attempts to stop the host within the provided timeout.

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            host.Start();

            await host.StopAsync(TimeSpan.FromSeconds(5));
        }
    }
}

StartAsync and StopAsync

xref:Microsoft.Extensions.Hosting.IHost.StartAsync* starts the app.

xref:Microsoft.Extensions.Hosting.IHost.StopAsync* stops the app.

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            await host.StartAsync();

            await host.StopAsync();
        }
    }
}

WaitForShutdown

xref:Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.WaitForShutdown* is triggered via the xref:Microsoft.Extensions.Hosting.IHostLifetime, such as xref:Microsoft.Extensions.Hosting.Internal.ConsoleLifetime (listens for Ctrl+C/SIGINT or SIGTERM). WaitForShutdown calls xref:Microsoft.Extensions.Hosting.IHost.StopAsync*.

public class Program
{
    public void Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            host.Start();

            host.WaitForShutdown();
        }
    }
}

WaitForShutdownAsync

xref:Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.WaitForShutdownAsync* returns a Task that completes when shutdown is triggered via the given token and calls xref:Microsoft.Extensions.Hosting.IHost.StopAsync*.

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = new HostBuilder()
            .Build();

        using (host)
        {
            await host.StartAsync();

            await host.WaitForShutdownAsync();
        }

    }
}

External control

External control of the host can be achieved using methods that can be called externally:

public class Program
{
    private IHost _host;

    public Program()
    {
        _host = new HostBuilder()
            .Build();
    }

    public async Task StartAsync()
    {
        _host.StartAsync();
    }

    public async Task StopAsync()
    {
        using (_host)
        {
            await _host.StopAsync(TimeSpan.FromSeconds(5));
        }
    }
}

xref:Microsoft.Extensions.Hosting.IHostLifetime.WaitForStartAsync* is called at the start of xref:Microsoft.Extensions.Hosting.IHost.StartAsync*, which waits until it's complete before continuing. This can be used to delay startup until signaled by an external event.

IHostingEnvironment interface

xref:Microsoft.Extensions.Hosting.IHostingEnvironment provides information about the app's hosting environment. Use constructor injection to obtain the IHostingEnvironment in order to use its properties and extension methods:

public class MyClass
{
    private readonly IHostingEnvironment _env;

    public MyClass(IHostingEnvironment env)
    {
        _env = env;
    }

    public void DoSomething()
    {
        var environmentName = _env.EnvironmentName;
    }
}

For more information, see xref:fundamentals/environments.

IApplicationLifetime interface

xref:Microsoft.Extensions.Hosting.IApplicationLifetime allows for post-startup and shutdown activities, including graceful shutdown requests. Three properties on the interface are cancellation tokens used to register Action methods that define startup and shutdown events.

Cancellation Token Triggered when…
xref:Microsoft.Extensions.Hosting.IApplicationLifetime.ApplicationStarted* The host has fully started.
xref:Microsoft.Extensions.Hosting.IApplicationLifetime.ApplicationStopped* The host is completing a graceful shutdown. All requests should be processed. Shutdown blocks until this event completes.
xref:Microsoft.Extensions.Hosting.IApplicationLifetime.ApplicationStopping* The host is performing a graceful shutdown. Requests may still be processing. Shutdown blocks until this event completes.

Constructor-inject the IApplicationLifetime service into any class. The sample app uses constructor injection into a LifetimeEventsHostedService class (an IHostedService implementation) to register the events.

LifetimeEventsHostedService.cs:

[!code-csharp]

xref:Microsoft.Extensions.Hosting.IApplicationLifetime.StopApplication* requests termination of the app. The following class uses StopApplication to gracefully shut down an app when the class's Shutdown method is called:

public class MyClass
{
    private readonly IApplicationLifetime _appLifetime;

    public MyClass(IApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public void Shutdown()
    {
        _appLifetime.StopApplication();
    }
}

Additional resources