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);return builder.Build();
到這裡中終於明白startup.cs類作用了。完成了基本的配置後,應用程式就可以啟動了。
WebHost.Run方法定義是在WebHostExtensions中,作為擴充方法存在的,Run方法中調用了WebHost的Start方法,WebHost的Start方法直接調用了IServer的Start方法進行服務啟動
//這個方法其實是調用程式裡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);return builder.Build();
到這裡中終於明白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處理管道進行處理。