The default template for ASP .NET core applications use the generic host. Generally, this is the area which is worked upon at the very beginning of the project and mostly it is not changed very often. Hence many times, we skip looking at the generic hosts related details.
In this article, let’s have a quick look at what generic host is and why it is used.
What is a Host ?
If we create a console application, then it is completely blank. The main method does not initialize host. And that’s why many times, when we work on the console application (which might be little unlikely in the “cloud”-era, but still possible), we may think of adding a dependency injection mechanism, or the code to add the appsettings.json config file.
These are the things that are taken care by the Host.
A host is an object that encapsulates an app’s resources, such as:
- Dependency injection (DI)
- Logging
- Configuration
IHostedService
implementations
We already know what a dependency injection is. I have covered some basics in my previous posts, you can check them if you want.
Logging is one of the aspects that is initialized by Host. You can configure different types of logging providers and then inject the abstractions (like ILogger) to use the logging APIs.
Configuration abstractions help to load the configurations from various configuration providers. The most common configuration providers are environment variables and appsettings.json file. Initializing them is taken care by the Host.
IHostedService is a special interface in this whole system. When a host starts, it calls IHostedService.StartAsync on each implementation of IHostedService registered in the service container’s collection of hosted services.
So every service that we use (like dependency injection service or routing service) are the implementations of IHostedService. In a web app, one of the IHostedService
implementations is a web service that starts an HTTP server implementation.
Why ?
So, by now, we have understood that all the important and interdependent resources are created and managed by a single object Host.
Obvious question might be – why ? It is basically helpful for having complete control over startup and have complete control over shutdown to have a graceful shutdown of the application.
Host vs WebHost
If like me, you have been using .NET core since its early days, you might have heard about WebHost. There are parallel set of classes:
The purpose of these classes is same – to allow a single object to control the application’s startup and graceful shutdown.
WebHost is from previous versions of .NET core and it still exists as of today in .NET 5, because of backwards compatibility reasons.
How to initialize Host ?
Let’s have a look at how the Host is initialized. There are two important variations – http workload and non-http workload. These two variations use two different methods to initialize the Host.
Web App
A typical ASP .NET Core web application’s program.cs file looks as shown below.
The main method performs two important duties:
- Calls the
CreateHostBuilder
method to create and configure builder object - Then calls
Build
andRun
methods to start the Host.
As we can see, below are the highlights of the code:
- Host is a static class and we use
CreateDefaultBuilder
method to create the builder. - Then
ConfigureWebHostDefaults
is called to initialize the settings for the web application.
Console App
I am taking example of the console app as it is very general and can be used for any purpose.
Here the code is bit different:
- Host static class and call to
CreateDefaultBuilder
is same as for web applications - Then
ConfigureServices
call to configure the host builder. This can be used to configure additional services.
What does this code do ?
Let’s quickly try to understand what tasks these special methods perform.
I have taken below two sections from documentation only for ready to reference purpose. These details might vary depending on the version you are using. Hence, refer documentation for more accurate details.
CreateDefaultBuilder
- Sets the content root to the path returned by GetCurrentDirectory.
- Loads host configurations from
- environment variables prefixed with
DOTNET_
- And command line arguments
- environment variables prefixed with
- Loads application configurations from:
appsettings.json
appsettings.{environment}.json
- In development environment, User secrets are loaded
- environment variables
- and command line arguments
- Adds logging providers. The providers include console provider, debug provider, event source providers and optionally
- Then if application is in development environment, enables scope validation and dependency validation
ConfigureWebHostDefaults
- Loads host configuration from environment variables prefixed with
ASPNETCORE_
. - Sets the Kestrel server as the web server. Then configures it using the app’s hosting configuration providers
- Adds Host Filtering middleware.
- Adds Forwarded Headers middleware if
ASPNETCORE_FORWARDEDHEADERS_ENABLED
equalstrue
. - Enables IIS integration. For the IIS default options, see Host ASP.NET Core on Windows with IIS.
I hope you found this information useful. Let me know your thoughts.
Can you post an example which covers all these?
If you are looking for the code examples which use GenericHost, then I would suggest to refer my GitHub repository – https://github.com/manoj-choudhari-git/dotnet-on-thecodeblogger