Generic Host Builder in ASP .NET Core 3.1

By Shahed C on February 17, 2020

This is the seventh of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series will mostly focus on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.

Previous post:

NetLearner on GitHub:

In this Article:

G is for Generic Host Builder

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

7 thoughts on “Generic Host Builder in ASP .NET Core 3.1

  1. Pingback: Dew Drop – February 18, 2020 (#3135) | Morning Dew

  2. Pingback: The Morning Brew - Chris Alcock » The Morning Brew #2935

  3. Pingback: JavaScript, CSS, HTML & Other Static Files in ASP .NET Core 3.1 | Wake Up And Code!

  4. Pingback: How to migrate an ASP.NET MVC app from .NET Core 2.2 to .NET Core 3.1

  5. Pingback: Key Vault for ASP .NET Core 3.1 Web Apps | Wake Up And Code!

  6. Pingback: Worker Service in .NET Core 3.1 | Wake Up And Code!

  7. Pingback: Handling Errors in ASP .NET Core 3.1 | Wake Up And Code!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.