Search  
Always will be ready notify the world about expectations as easy as possible: job change page
Aug 25, 2020

G is for Generic Host Host Builder

Source:
Views:
952

The Generic Host Builder in ASP .NET Core was introduced in v2.1, but only meant for non-HTTP workloads. However, it has now replaced the Web Host Builder as of v3.0 in 2019.


Generic Host Builder in ASP .NET Core 3.x

History Lesson: Generic Host Builder in 2.x

So, if the Generic Host Builder wasn’t used for web hosting in v2.x, what was it there for? The aforementioned non-HTTP workloads include a number of capabilities according to the 2.2 documentation, including:

  • app config, e.g. set base path, add hostsettings.json, env variables, etc
  • dependency injection, e.g. various hosted services
  • logging capabilities, e.g. console logging

The HostBuilder class is available from the following namespace, implementing the IHostBuilder interface:

using Microsoft.Extensions.Hosting;

At a minimum, the Main() method of your .NET Core app would look like the following:

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

    await host.RunAsync();
}

Here, the Build() method initializes the host, so (as you may expect) it can only be called once for initialization. Additional options can be configured by calling the ConfigureServices() method before initializing the host with Build().

var host = new HostBuilder().ConfigureServices((hostContext, services) =>
{
    services.Configure<HostOptions>(option =>
    {
        // option.SomeProperty = ...
    });
}).Build();

Here, the ConfigureServices() method takes in a HostBuilderContext and an injected collection of IServiceCollection services. The options set in the Configure() can be used to set additional HostOptions. Currently, HostOptions just has one property, i.e. ShutdownTimeout.

You can see more configuration capabilities in the official sample, broken down into the snippets below:

Host Config Snippet:

.ConfigureHostConfiguration(configHost =>
{
    configHost.SetBasePath(Directory.GetCurrentDirectory());
    configHost.AddJsonFile("hostsettings.json", optional: true);
    configHost.AddEnvironmentVariables(prefix: "PREFIX_");
    configHost.AddCommandLine(args);
})

App Config Snippet:

.ConfigureAppConfiguration((hostContext, configApp) =>
{
    configApp.AddJsonFile("appsettings.json", optional: true);
    configApp.AddJsonFile(
        $"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json",
        optional: true);
    configApp.AddEnvironmentVariables(prefix: "PREFIX_");
    configApp.AddCommandLine(args);
})

Dependency Injection Snippet:

.ConfigureServices((hostContext, services) =>
{
    services.AddHostedService<LifetimeEventsHostedService>();
    services.AddHostedService<TimedHostedService>();
})

Logging Snippet:

.ConfigureLogging((hostContext, configLogging) =>
{
    configLogging.AddConsole();
    configLogging.AddDebug();
})

More History: Web Host Builder in 2.x

The WebHostBuilder class was made available from the following namespace (specific to ASP .NET Core), implementing the IWebHostBuilder interface:

using Microsoft.AspNetCore.Hosting;

The Web Host Builder in ASP .NET Core was used for hosting web apps in v2.x. As mentioned in the previous section, it has since been replaced by the Generic Host Builder as of v3.0. At a minimum, the Main() method of your ASP .NET Core 2.x web app would have looked like the following:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

If you’re not familiar with the shorthand syntax of the helper method CreateWebHostBuilder() shown above, here’s what it would normally look like, expanded:

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    return WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
}

NOTE: This type of C# syntax is known as an Expression Body Definition, introduced for methods in C# 6.0, and additional features in C# 7.0.

The CreateDefaultBuilder() method performs a lot of “magic” behind the scenes, by making use of pre-configured defaults. From the official documentation, here is a summary of the default configuration from the Default Builder:

For more information on some of the above, here are some other blog posts that you may find useful:

Generic Host Builder for Web Apps in 3.x

As of 2019, ASP .NET Core 3.x allows you to use the updated Generic Host Builder instead of the Web Host Builder in your web apps. The ASP .NET Core templates were updated to include the Generic Host Builder as of v3.0 Preview 2. You should use v3.1 since it’s a LTS (Long-Time Support) release.

At a minimum, the Main() method of your .NET Core 3.1 web app would now look like the following:

public static void Main(string[] args)
{
    CreateHostBuilder(args)
       .Build()
       .Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
   Host.CreateDefaultBuilder(args)
      ConfigureWebHostDefaults(webBuilder =>
      {
          webBuilder.UseStartup<Startup>();
      });

Here’s an expanded representation of the CreateHostBuilder() method:

public static IHostBuilder CreateHostBuilder(string[] args)
{
    return Host.CreateDefaultBuilder(args)
       ConfigureWebHostDefaults(webBuilder =>
       {
           webBuilder.UseStartup<Startup>();
       });
}

This CreateHostBuilder() method in the 3.x template looks very similar to the 2.x call to CreateWebHostBuilder() mentioned in the previous section. In fact, the main difference is that the call to WebHost.CreateDefaultBuilder() is replaced by Host.CreateDefaultBuilder(). Using the CreateDefaultBuilder() helper method makes it very easy to switch from v2.x to v3.x.

Another difference is the call to ConfigureWebHostDefaults(). Since the new host builder is a Generic Host Builder, it makes sense that we have to let it know that we intend to configure the default settings for a Web Host. The ConfigureWebHostDefaults() method does just that.

Going forward, it’s important to know the following:

  • WebHostBuilder has now been deprecated and could be removed in the near future.
  • However, the IWebHostBuilder interface will remain.
  • You won’t be able to inject just any service into the Startup class…
  • … instead, you have IHostingEnvironment and IConfiguration.

If you’re wondering about the reason for the limitation for injecting services, this change prevents you from injecting services into the Startup class before ConfigureServices() gets called.

References

Send message
Type
Email
Your name
*Message