asp.net core mvc是微軟開源的跨平臺的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平臺,然後又增加了一些非常實用的新功能,比如taghelper,viewcomponent,DependencyInjection等,現在開始asp.net core mvc剖析之旅。 任何應用 ...
asp.net core mvc是微軟開源的跨平臺的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平臺,然後又增加了一些非常實用的新功能,比如taghelper,viewcomponent,DependencyInjection等,現在開始asp.net core mvc剖析之旅。
任何應用程式都有入口點,MVC中也如此,通過新框架創建的MVC程式里,有一個特殊的文件Program.cs,裡面包含了一個Main方法,這個方法相信大家都不陌生,控制台應用程式也有類似的Main方法,這個方式其實就是MVC程式的入口方法,那我們來看一下這個方法里主要做了什麼工作?
public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); }
從上面的代碼我們可以看出,通過WebHostBuilder類Build了一個IWebHost對象,然後調用host.Run方法完成應用程式啟動。那我們再來看一下,WebHost是如何被Build出來的。在Hosting項目中最終找到了WebHostBuilder類的蹤影,Build方法里有幾句關鍵代碼:
//創建應用程式依賴註入的IServiceCollection對象,這個後面會單獨去講解
var hostingServices = BuildHostingServices(); var hostingContainer = hostingServices.BuildServiceProvider();
//實例化WebHost對象 var host = new WebHost(hostingServices, hostingContainer, _options, _config);
//初始化 host.Initialize();
在WebHost類中找到Initialize()方法,方法里調用了BuildApplication完成http請求處理管道的構建。我們來看下構建處理管道的過程
//這個方法其實是調用程式里Startup類中的ConfigureServices方法,完成服務依賴註冊
EnsureApplicationServices();
//IServer的相關操作 EnsureServer(); var builderFactory = _applicationServices.GetRequiredService<IApplicationBuilderFactory>(); var builder = builderFactory.CreateBuilder(Server.Features); builder.ApplicationServices = _applicationServices; var startupFilters = _applicationServices.GetService<IEnumerable<IStartupFilter>>(); Action<IApplicationBuilder> configure = _startup.Configure; foreach (var filter in startupFilters.Reverse()) {
//調用Startup類中的Configure方法註冊處理中間件(middleware) configure = filter.Configure(configure); } configure(builder);
到這裡中終於明白startup.cs類作用了。完成了基本的配置後,應用程式就可以啟動了。
WebHost.Run方法定義是在WebHostExtensions中,作為擴展方法存在的,Run方法中調用了WebHost的Start方法,WebHost的Start方法直接調用了IServer的Start方法進行服務啟動
Server.Start(new HostingApplication(_application, _logger, diagnosticSource, httpContextFactory));
_application:http請求處理管道
httpContextFactory:httpcontext工廠,每個http請求都會對應一個httpcontext對象,這個httpcontext就由這個工廠進行創建,這個工廠在HttpAbstractions項目中。
IServer啟動方法里會啟動請求監聽,當http請求過來後,首先調用HostingApplication(IHttpApplication類型)的CreateContext創建HttpContext對象,CreateContext會依賴上面提到的httpContextFactory,HttpContext創建後就會調用HostingApplication的ProcessRequestAsync方法進行請求處理:
public Task ProcessRequestAsync(Context context) { return _application(context.HttpContext); }
ProcessRequestAsync方法里很簡單,直接把http請求放入http處理管道進行處理。
下一篇文章會介紹KestrelServer如何監聽請求,並交給處理管道進行處理的。