《ASP.NET Core 高效能系列》ASP.NET Core的啟動過程(1)
一、一切從頭開始
簡述:知道事情的真相就應該從頭 開始,下面我們程式碼先行
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
可見,關鍵是我們需要研究CreateHostBuilder整個方法內部做了什麼,不要簡單地看這個方法,真實情況涉及很深.本文簡化很多問題來說明
二、先讓我們熟悉幾個資料結構
2.1 IHostBuilder (暫時寫這一個,後續再增加)
public interface IHostBuilder { IDictionary<object, object> Properties { get; } //宿主程式的配置 IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate); //應用程式的配置 IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate); //新增service到容器 IHostBuilder ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate); IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory); //覆蓋用於建立ServiceProvider的工廠。 IHostBuilder UseServiceProviderFactory<TContainerBuilder>(Func<HostBuilderContext, IServiceProviderFactory<TContainerBuilder>> factory); / /配置依賴注入的容器 IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderContext, TContainerBuilder> configureDelegate); IHost Build(); }
得出簡要的分析和猜測:CreateHostBuilder中設定Asp.net core中所需諸多原始素材:配置資訊(包括環境等),IOC所需的種種素材,建立web程式所需的宿主WebHost然後將上面的素材同時傳給WebHost.......
三、CreateDefaultBuilder方法內部做了什麼
public static IHostBuilder CreateDefaultBuilder(string[] args) { HostBuilder hostBuilder = new HostBuilder(); hostBuilder.UseContentRoot(Directory.GetCurrentDirectory());//設定Host的配置資訊 hostBuilder.ConfigureHostConfiguration((Action<IConfigurationBuilder>)delegate(IConfigurationBuilder config) { config.AddEnvironmentVariables("DOTNET_"); if (args != null) { config.AddCommandLine(args); } });
//設定應用程式的配置資訊 hostBuilder.ConfigureAppConfiguration((Action<HostBuilderContext, IConfigurationBuilder>)delegate(HostBuilderContext hostingContext, IConfigurationBuilder config) { IHostEnvironment hostingEnvironment = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).AddJsonFile("appsettings." + hostingEnvironment.EnvironmentName + ".json", optional: true, reloadOnChange: true); if (hostingEnvironment.IsDevelopment() && !string.IsNullOrEmpty(hostingEnvironment.ApplicationName)) { Assembly assembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName)); if (assembly != null) { config.AddUserSecrets(assembly, optional: true); } } config.AddEnvironmentVariables(); if (args != null) { config.AddCommandLine(args); } })//設定日誌的相關配置
.ConfigureLogging((Action<HostBuilderContext, ILoggingBuilder>)delegate(HostBuilderContext hostingContext, ILoggingBuilder logging) { bool num = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); if (num) { logging.AddFilter<EventLogLoggerProvider>((LogLevel level) => level >= LogLevel.Warning); } logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); logging.AddEventSourceLogger(); if (num) { logging.AddEventLog(); } }).UseDefaultServiceProvider((Action<HostBuilderContext, ServiceProviderOptions>)delegate(HostBuilderContext context, ServiceProviderOptions options) { bool validateOnBuild = options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); options.ValidateOnBuild = validateOnBuild; }); return hostBuilder; }
我們先總結一些知識點和注意事項
1.程式的預設的根目錄採用了Directory.GetCurrentDirectory()也就是Environment.CurrentDirectory,那麼這意味著我們在用其它程式啟動應用時需要手動指定當前工作目錄,避免發生變化.
2.asp.net core中兩個路徑的區別
ContentRoot: C:\MyApp\wwwroot WebRoot: C:\MyApp\wwwroot\wwwroot
3.asp.net core中配置檔案的優先順序問題
命令列>環境變數>自我訂製的配置(AddUserSecrets)>和當前環境相匹配的appsettings.json中的配置>大於appsettings.json中的配置
關於AddUserSecrets是什麼這裡簡單一言以蔽之:每個開發人員有自己特性的配置資料,這些配置資訊僅僅屬於個人,不能提交給團隊成員,
但是又不想不團隊共有的配置所影響. 剩下的自行去了解,關鍵是上面的優先順序
和當前環境相匹配的appsettings.json如appsettings.Development.json
4.系統會預設新增日誌行為如下
a.windows會新增事件(level >= LogLevel.Warning)
b.預設會將採用appsettings.json中Logging節點下的配置情況
c.日誌資訊預設會顯示咋控制檯和除錯中
四、 Startup 類
主要作用:配置服務和應用的請求管道。ASP.NET Core 按照約定命名為 Startup作為 Startup 類:
1.可選擇性地包括 ConfigureServices 方法以配置應用的服務 。 服務是一個提供應用功能的可重用元件。
在 ConfigureServices 中註冊服務,並通過依賴關係注入 (DI) 或 ApplicationServices 在整個應用中使用服務 。
2.包括 Configure 方法以建立應用的請求處理管道。
在啟動時,ASP.NET Core會呼叫 ConfigureServices 和 Configure:
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // 該方法會被執行時自動呼叫,通過此方法可將service新增到容器中. public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); } // 該方法會被執行時自動呼叫. 使用此方法配置 HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } }
Startup總結:
從第一部分我們可以看到在程式啟動時通過webBuilder.UseStartup<Startup>()將Startup指定給Host,
注意:Host能夠提供 Startup 類建構函式可用的某些服務。 應用自身可通過 ConfigureServices方法 新增你需要的其他服務。
主機和應用提供的這些服務都可以在 Configure 和整個應用中使用。
使用泛型Host (IHostBuilder) 時,只能將以下服務型別注入 Startup 建構函式:
IWebHostEnvironment
IHostEnvironment
IConfiguration
未完待續,不足之處歡迎請指正.