ASP.NET Core框架深度学习(一) Hello World
对于学习Core的框架,对我帮助最大的一篇文章是Artech的《200行代码,7个对象——让你了解ASP.NET Core框架的本质》,最近我又重新阅读了一遍该文。本系列文章就是结合我的阅读心得,一起来搭建一个迷你的Core框架。
本文相关代码在码云上,,链接如下
https://gitee.com/qixinbo/MyKestrelServer/tree/master/CoreMini/CoreMini
还有部分是core的源码,链接如下
https://github.com/aspnet/AspNetCore/tree/master/src/Http
1、从Hello World谈起当我们最开始学习一门技术的时候都喜欢从Hello World来时,貌似和我们本篇的主题不太搭。但事实却非如此,在我们看来如下这个Hello World是对ASP.NET Core框架本质最好的体现。
public class Program { public static void Main() => new WebHostBuilder() .UseKestrel() .Configure(app => app.Run(context => context.Response.WriteAsync("Hello World!"))) .Build() .Run(); }
如上这个Hello World程序虽然人为地划分为若干行,但是整个应用程序其实只有一个语句。这个语句涉及到了ASP.NET Core程序两个核心对象WebHost和WebHostBuilder。我们可以将WebHost理解为寄宿或者承载Web应用的宿主,应用的启动可以通过启动作为宿主的WebHost来实现。至于WebHostBuilder,顾名思义,就是WebHost的构建者。
在调用WebHostBuilder的Build方法创建出WebHost之前,我们调用了它的两个方法,其中UseKestrel旨在注册一个名为Kestrel的服务器,而Configure方法的调用则是为了注册一个用来处理请求的中间件,后者在响应的主体内容中写入一个“Hello World”文本。
(Configure本质上是把一个委托加入到了中间件的集合中。)
UseKestrel代码
public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder) { //同样是ConfigureServices,跟平时我们startup里面进行注册是一样的 return hostBuilder.ConfigureServices(services => { // Don‘t override an already-configured transport services.TryAddSingleton<ITransportFactory, SocketTransportFactory>(); services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>(); services.AddSingleton<IServer, KestrelServer>(); }); }
当我们调用Run方法启动作为应用宿主的WebHost的时候,后者会利用WebHostBuilder提供的服务器和中间件构建一个请求处理管道。这个由一个服务器和若干中间件构成的管道就是ASP.NET Core框架的核心,我们接下来的核心任务就是让大家搞清楚这个管道是如何被构建起来的,以及该管道采用怎样的请求处理流程。
Servicer有StartAsync或者叫run的方法
run的代码
public static void Run(this IWebHost host) { host.RunAsync().GetAwaiter().GetResult(); } /// <summary> /// Runs a web application and returns a Task that only completes when the token is triggered or shutdown is triggered. /// </summary> /// <param>The <see cref="IWebHost"/> to run.</param> /// <param>The token to trigger shutdown.</param> public static async Task RunAsync(this IWebHost host, CancellationToken token = default) { // Wait for token shutdown if it can be canceled if (token.CanBeCanceled) { await host.RunAsync(token, shutdownMessage: null); return; } // If token cannot be canceled, attach Ctrl+C and SIGTERM shutdown var done = new ManualResetEventSlim(false); using (var cts = new CancellationTokenSource()) { var shutdownMessage = host.Services.GetRequiredService<WebHostOptions>().SuppressStatusMessages ? string.Empty : "Application is shutting down..."; AttachCtrlcSigtermShutdown(cts, done, shutdownMessage: shutdownMessage); try { await host.RunAsync(cts.Token, "Application started. Press Ctrl+C to shut down."); } finally { done.Set(); } } } private static async Task RunAsync(this IWebHost host, CancellationToken token, string shutdownMessage) { using (host) { await host.StartAsync(token); var hostingEnvironment = host.Services.GetService<IHostingEnvironment>(); var options = host.Services.GetRequiredService<WebHostOptions>(); if (!options.SuppressStatusMessages) { Console.WriteLine($"Hosting environment: {hostingEnvironment.EnvironmentName}"); Console.WriteLine($"Content root path: {hostingEnvironment.ContentRootPath}"); var serverAddresses = host.ServerFeatures.Get<IServerAddressesFeature>()?.Addresses; if (serverAddresses != null) { foreach (var address in serverAddresses) { Console.WriteLine($"Now listening on: {address}"); } } if (!string.IsNullOrEmpty(shutdownMessage)) { Console.WriteLine(shutdownMessage); } } await host.WaitForTokenShutdownAsync(token); } }
View Code 2、ASP.NET Core Mini温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/40461.html