Author: cmliu; .NET Core started what has been done
.NET Core default process at startup, you can save it as a picture, zoom in on the local
.NET Core default templates have done, first posted inside the Program.cs template
public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); }
Interpretation:
1, the method first calls the main inlet CreateWebHostBuilder (string [] args) method to obtain a [constructed by the Web host WebHostBuilder]
2, CreateWebHostBuilder (string [] args) method is invoked first: WebHost.CreateDefaultBuilder (args) to create a default WebHostBuilder
In WebHost.CreateDefaultBuilder, first read command, ContentRoot configuration; Kestrel and specify the configuration log provider, and related middleware preferentially executed, and clearly injected IServer implementation class KestrelServer;
And configure IIS-related service //WebHost.CreateDefaultBuilder part of the source code
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{ var builder = new WebHostBuilder(); if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey))) { builder.UseContentRoot(Directory.GetCurrentDirectory()); } if (args != null) { builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build()); }
// This method specifies the implementation class Server underlayer is KestrelServer () builder.UseKestrel((builderContext, options) => { // omitted other code
}) .ConfigureAppConfiguration((hostingContext, config) => { // omitted other code }) .ConfigureLogging((hostingContext, logging) => { // omitted other code }) .ConfigureServices((hostingContext, services) => { // omitted other code }) .UseIIS () .UseIISIntegration() .UseDefaultServiceProvider((context, options) => { // omitted other code }); return builder; }
3, call WebHost.CreateDefaultBuilder (args) Returns the object UseStartup <Startup> () method; registration service for the container (ConfigureServices method), and a pipe register (Configure Method)
Startup explain here in ConfigureServices, Configure the following two methods with [the] Program class ConfigureServices, Configure effect is the same method, are registered for the service container (ConfigureServices method), and a pipe register (Configure Method )
public static IWebHostBuilder CreateWebHostBuilder(string[] args) { var webHostBuilder = WebHost.CreateDefaultBuilder(args).ConfigureServices((services) => { // omitted other code, register for service containers }). Configure ((app) => { // omitted other code, for registration pipe }); return webHostBuilder; }
4, Statrtup code is omitted, later interpretation
5, main method call CreateWebHostBuilder (string [] args) Build the method returns WebHostBuilder
Build in this method, the direct initialization and return to a WebHost, and specifying WebHost of IServiceCollection (service), IServiceProvider (container), which has a WebHost Server object, the object actually KestrelServer
6, Run WebHost object method Build returned calls for starting the server
******* fact WebHost.Run method, first obtains a ApplicationBuilder (Configure method Startip is in the injection pipe for the class), and a method using ApplicationBuilder.Build descending conduit delegation chain construct RequestDelegate
******* ApplicationBuilder.Build process, will most middleware 404 to the last intermediate injection pipe
RequestDelegate ******* obtained using the log, HttpContextFactory relevant parameters, construct a HostingApplication
******* lowest level: asynchronously start WebHost.Server.StartAsync, namely StartAsync method KestrelServer call and specify the method [HostingApplication in this case KestrelServer've got a pipeline owned HostingApplication RequestDelegate]
internal class WebHost : IWebHost { //省略其他代码 private readonly IServiceCollection _applicationServiceCollection; private readonly IServiceProvider _hostingServiceProvider; private IServiceProvider _applicationServices; private IServer Server { get; set; } //省略其他代码 public WebHost(IServiceCollection appServices,IServiceProvider hostingServiceProvider, WebHostOptions options,IConfiguration config,AggregateException hostingStartupErrors) { // omitted other code _applicationServiceCollection = AppServices; _hostingServiceProvider = hostingServiceProvider; // omitted other code } // other code omitted public the IServiceProvider Services { get { return _applicationServices; } } // omitted other code public void the Start () { StartAsync().GetAwaiter().GetResult(); } // other code omitted public Virtual the async the Task startAsync (a CancellationToken CancellationToken = default ) { // omitted other code // Construction RequestDelegate delegation chain pipe var file application = BuildApplication (); _applicationLifetime = _applicationServices.GetRequiredService<IApplicationLifetime>() as ApplicationLifetime; _hostedServiceExecutor = _applicationServices.GetRequiredService <HostedServiceExecutor> (); var diagnosticSource = _applicationServices.GetRequiredService <DiagnosticListener> (); var httpContextFactory = _applicationServices.GetRequiredService <IHttpContextFactory> (); // RequestDelegate ducts for delegation chain construct HostingApplication var hostingApp = new new HostingApplication (the Application, _logger, diagnosticSource, httpContextFactory); // start KestrelServer server and HostingApplication bound to KestrelServer the await Server.StartAsync (hostingApp, CancellationToken) .ConfigureAwait (to false ); // omitted other code } // omitted other codes private RequestDelegate BuildApplication() { try { //省略其他代码 var builderFactory = _applicationServices.GetRequiredService<IApplicationBuilderFactory>(); var builder = builderFactory.CreateBuilder(Server.Features); builder.ApplicationServices = _applicationServices;
// other code omitted
return builder.Build (); } catch (Exception ex) {
// other code omitted
} } // omitted other code }
7, after KestrelServer start HttpListener, start listening for requests from the client browser
8, KestrelServer receiving the browser request, the HttpContext constructed request parameters, and select a corresponding HTTP protocol handler class by class protocol processing method ProcessRequests (PR method legendary)
public abstract partial class HttpProtocol : IHttpResponseControl { //HTTP协议类调用HttpApplication private async Task ProcessRequests<TContext>(IHttpApplication<TContext> application) { while (_keepAlive) { // omitted other code try { // omitted other code the await application.ProcessRequestAsync (httpContext); // omitted other code } the catch (BadHttpRequestException EX) { // omitted other code } // other code omitted } } }
9, PR method will be to call HostingApplication of ProcessRequestAsync KestrelServer, and ProcessRequestAsync is the HttpContext to RequestDelegate pipeline deal
public class HostingApplication : IHttpApplication<HostingApplication.Context> { // delegation chain conduit Private Readonly RequestDelegate _Application; // omitted other code public HostingApplication ( RequestDelegate application, ILogger logger DiagnosticListener diagnosticSource, IHttpContextFactory httpContextFactory) { _Application = file application; // omitted other code } // PR method, call delegation chain process requests public Task ProcessRequestAsync (Context context) { return _application(context.HttpContext); }
// other code omitted
}