Written in front

The generic host builder in ASP .NET Core was introduced in v2.1. The application builds the host at startup, and the host acts as an object for encapsulating application resources and application startup and lifetime management. Its main features include configuration initialization (including loading configuration and configuration conversion to a common key-value pair format), creating a managed environment and Host common context, dependency injection, and more.

In .NET Core 3.0, IHostBuilder is used to create Host, and Web Host is no longer recommended. It is recommended to use generic host. The main reason is that the original Universal Host is only suitable for non-HTTP load, in order to provide a wider range. The host solution needs to separate the HTTP pipe from the interface of the web host. But the web host will still be backward compatible.


DotNET_Core_3.0_source-understanding_Host_(1)_0.png

 

Create a universal host in .NET Core 3.0

The following code is the template code provided in V3.0. You can see that in the process of creating the host, the way to create WebHostBuilder has been abandoned.

   1:   public  class Program
   2:   {
   3:       public  static  void Main( string [] args)
   4:       {
   5:           CreateHostBuilder(args).Build().Run();
   6:       }
   7:   
   8:       public  static IHostBuilder CreateHostBuilder( string [] args) =>
   9:           Host.CreateDefaultBuilder(args)
  10:               .ConfigureWebHostDefaults(webBuilder =>
  11:               {
  12:                   webBuilder.UseStartup<Startup>();
  13:               });
  14:   }

And in .NET Core 2.X

   1:   public  class Program
   2:   {
   3:      public  static  void Main( string [] args)
   4:      {
   5:         CreateWebHostBuilder(args).Build().Run();
   6:      }
   7:   
   8:      public  static IWebHostBuilder CreateWebHostBuilder( string [] args) =>
   9:         WebHost.CreateDefaultBuilder(args)
  10:            .UseStartup<Startup>();
  11:   }

The CreateHostBuilder() method provided in the V3.0 template looks very similar to CreateWebHostBuilder() in V2.X.

The main difference is that WebHost.CreateDefaultBuilder() is replaced by Host.CreateDefaultBuilder(). It is very easy to switch from v2.x to v3.0 using the CreateDefaultBuilder() helper method.

Another difference is the call to ConfigureWebHostDefaults(). Since the new host builder is a generic host builder, we must let it know that we are going to configure default settings for the web host. These default configurations can be implemented in the ConfigureWebHostDefaults() method.

CreateDefaultBuilder

The method Microsoft.Extensions.Hosting.Host, which is a static class, has two methods, one with the parameter CreateDefaultBuilder (string[] args), one is no parameter.

The no-parameter method source code is as follows,

   1:   public  static IHostBuilder CreateDefaultBuilder() =>
   2:               CreateDefaultBuilder(args: null );

You can see that the method actually sets the default value.

The IHostBuilder CreateDefaultBuilder(string[] args) method has the following main functions:

Create a HostBuilder object

   1:   var builder = new HostBuilder();

Specify the content root directory to be used by Host

   1:   builder.UseContentRoot(Directory.GetCurrentDirectory());

Configuration initialization (environment variables, appsettings.json, User Secrets)

   1:   builder.ConfigureHostConfiguration(config =>
   2:   {
   3:       config.AddEnvironmentVariables(prefix: "DOTNET_" );
   4:       if (args != null )
   5:       {
   6:           config.AddCommandLine(args);
   7:       }
   8:   });
   9:   
  10:   builder.ConfigureAppConfiguration((hostingContext, config) =>
  11:   {
  12:       var env = hostingContext.HostingEnvironment;
  13:   
  14:       config.AddJsonFile( "appsettings.json" , optional: true , reloadOnChange: true )
  15:             .AddJsonFile($ "appsettings.{env.EnvironmentName}.json" , optional: true , reloadOnChange: true );
  16:   
  17:       if (env.IsDevelopment() && ! string .IsNullOrEmpty(env.ApplicationName))
  18:       {
  19:           var appAssembly = Assembly.Load( new AssemblyName(env.ApplicationName));
  20:           if (appAssembly != null )
  21:           {
  22:               config.AddUserSecrets(appAssembly, optional: true );
  23:           }
  24:       }
  25:   
  26:       config.AddEnvironmentVariables();
  27:   
  28:       if (args != null )
  29:       {
  30:           config.AddCommandLine(args);
  31:       }
  32:   })

Log

   1:   .ConfigureLogging((hostingContext, logging) =>
   2:   {
   3:       logging.AddConfiguration(hostingContext.Configuration.GetSection( "Logging" ));
   4:       logging.AddConsole();
   5:       logging.AddDebug();
   6:       logging.AddEventSourceLogger();
   7:   })

Enable scope validation in development environment mode

   1:   .UseDefaultServiceProvider((context, options) =>
   2:   {
   3:       var isDevelopment = context.HostingEnvironment.IsDevelopment();
   4:       options.ValidateScopes = isDevelopment;
   5:       options.ValidateOnBuild = isDevelopment;
   6:   });

Build

The Build() method is in Microsoft.Extensions.Hosting, and the method will only be executed once, of course, this time is only in the same instance.

   1:   public IHost Build()
   2:   {
   3:       if (_hostBuilt)
   4:       {
   5:           throw  new InvalidOperationException( "Build can only be called once." );
   6:       }
   7:       _hostBuilt = true ;
   8:   
   9:       BuildHostConfiguration();
  10:       CreateHostingEnvironment();
  11:       CreateHostBuilderContext();
  12:       BuildAppConfiguration();
  13:       CreateServiceProvider();
  14:   
  15:       return _appServices.GetRequiredService<IHost>();
  16:   }

The method mainly includes the following functions:

Create HostingEnvironment

Create a HostBuilderContext

Configuration initialization and format standardization

DI (create IHostEnvironment, IHostApplicationLifetime, IHostLifetime, IHost)

Run

The Run method runs the application and blocks the calling thread until the host closes

   1:   public  static  void Run( this IHost host)
   2:   {
   3:       host.RunAsync().GetAwaiter().GetResult();
   4:   }

The following is the source code of RunAsync, where the application can be automatically closed by setting the value of CancellationToken.

   1:   public  static async Task RunAsync( this IHost host, CancellationToken token = default )
   2:   {
   3:       try
   4:       {
   5:           await host.StartAsync(token);
   6:   
   7:           await host.WaitForShutdownAsync(token);
   8:       }
   9:       finally
  10:       {
  11:   #if DISPOSE_ASYNC
  12:           if (host is IAsyncDisposable asyncDisposable)
  13:           {
  14:               await asyncDisposable.DisposeAsync();
  15:           }
  16:           else
  17:   #endif
  18:           {
  19:               host.Dispose();
  20:           }
  twenty one:   
  22:       }
  23:   }

Orignal link:https://www.cnblogs.com/edison0621/p/11025310.html