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)
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.
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.
A typical ASP .NET Core web application’s program.cs file looks as shown below.
The main method performs two important duties:
- Calls the
CreateHostBuildermethod to create and configure builder object
- Then calls
Runmethods to start the Host.
As we can see, below are the highlights of the code:
- Host is a static class and we use
CreateDefaultBuildermethod to create the builder.
ConfigureWebHostDefaultsis called to initialize the settings for the web application.
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
CreateDefaultBuilderis same as for web applications
ConfigureServicescall 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.
- Sets the content root to the path returned by GetCurrentDirectory.
- Loads host configurations from
- environment variables prefixed with
- And command line arguments
- environment variables prefixed with
- Loads application configurations from:
- 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
- Loads host configuration from environment variables prefixed with
- 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
- 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.