《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
WebRoot:      C:\MyApp\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

 

  另外這裏補下:https://www.cnblogs.com/artech/p/di-in-asp-net-core-3.html (ASP.NET Core應用的7種依賴注入方式)

此文講了ASP.NET Core中使用了依賴注入的各類場景,本質參考我上文就知道發生了什麼

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章