ASP.NET Core - 入口文件

来源:https://www.cnblogs.com/wewant/archive/2023/02/11/17107311.html
-Advertisement-
Play Games

最近遇到需求需要把控制台程式做成 windows服務 的形式運行。改成 windows服務 後,程式無法訪問共用網路文件,訪問提示“Access to the path '網路路徑' is denied.“,拒絕訪問,原因是當前服務的用戶憑證無許可權訪問,於是需要修改當前服務的用戶憑證,改為可訪問共用 ...


1. 入口文件

  一個應用程式總有一個入口文件,是應用啟動代碼開始執行的地方,這裡往往也會涉及到應用的各種配置。當我們接觸到一個新框架的時候,可以從入口文件入手,瞭解入口文件,能夠幫助我們更好地理解應用的相關配置以及應用的工作方式。

  .Net Core 應用的入口文件是 Program.cs,這裡是應用啟動的地方。在 .Net 6 之前的版本,Program.cs 文件是下麵這樣的,這是創建一個 Web 項目時的預設代碼。

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>();
			});
}

  其中 Main 方法就是應用啟動的入口。可以看到在應用啟動的時候,通過 建造者模式 創建了一個主機,併進行了相關的配置,最後將其運行起來。

  從代碼中可以看到,在對主機進行配置的時候,使用到了 Startup 類,在 .Net 6 之前的版本,Startup 類承擔應用的啟動任務,是應用配置的主要地方。

2. Startup 類

2.1 Startup類結構

  Startup 類支持兩種定義方式,一種是實現 IStartup 介面,一種是基於約定的。無論哪一種,Startup 類的基本結構都包含以下兩個個關鍵函數。整體來說,基於約定的 Startup 類更加靈活。

  • ConfigureServices方法
  • Configure方法

image

2.1.2 ConfigureServices 方法

  • 該方法是可選的
  • 該方法用於添加服務到DI容器中
  • 該方法在 Configure 方法之前被調用
  • 基於約定的情況下,該方法要麼無參數,要麼只能有一個參數且類型必須為 IServiceCollection
  • 該方法內的代碼大多是形如 Add{Service} 的擴展方法

2.1.3 Configure方法

  • 該方法是必須的
  • 該方法用於配置 HTTP 請求管道,通過向管道添加中間件,應用不同的響應方式。
  • 該方法在 ConfigureServices 方法之後被調用
  • 基於約定的情況下,該方法中的參數可以接受任何已註入到DI容器中的服務
  • 該方法內的代碼大多是形如 Use{Middleware} 的擴展方法
  • 該方法內中間件的註冊順序與代碼的書寫順序是一致的,先註冊的先執行,後註冊的後執行

  另外還有構造函數,當使用通用主機時,Startup 構造函數支持註入以下三種服務類型,在 Startup 類中全局進行使用:

  • IConfiguration
  • IWebHostEnvironment
  • IHostEnvironment

2.2 預設Startup

  所謂預設Startup,就是應用啟動配置不用 Startup 類,直接在 ConfigureWebHostDefaults 中進行配置。

publicstaticIHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
          // ConfigureServices 可以調用多次,最終會將結果聚合
	  webBuilder.ConfigureServices(services =>
	  {
	  })
	  // Configure 如果調用多次,則只有最後一次生效.
	  .Configure(app =>
	  {
		// Configure調用之前,ConfigureServices已經調用,容器對象已經生成,所以這裡可以通過容器直接解析需要的對象
		var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
          });
        });

2.3 多環境配置

  .NET Core 框架支持多環境開發,可以通過環境變數 ASPNETCORE_ENVIRONMENT 來設置應用當前的運行環境,以實現一套代碼在不同環境下運行,根據環境區分一定的行為,支持開發、測試、預發佈、生成環境下不同條件、不同配置的運行場景。

  我們可以直接在機器的環境變數中進行設置,在項目的 Properties 文件夾裡面的“launchSettings.json”文件進行配置,該文件是用於配置VS中項目啟動的,在 profiles 節點中通過不同的 json 對象配置當前應用的啟動模式,而描述啟動模式的 json 對象支持的欄位中有一個 environmentVariables 節點,可以通過鍵值對方式配置環境變數。

image

  這裡配置的環境變數只會在當前項目中起作用。若應用運行環境中從未對 ASPNETCORE_ENVIRONMENT 環境變數進行配置,則預設為 Production 。而我們其實可以將 ASPNETCORE_ENVIRONMENT 設置為任意值。

  之後,這些環境變數會在主機初始化的時候作為主機配置被載入到應用中,這些會在後面的配置系統中詳細講到。而在代碼中,我們可以通過註入 IWebHostEnvironment 服務獲取到當前應用的運行環境。例如下麵在 StartUp 中通過判斷環境執行不同的應用初始化邏輯。

image

  IWebHostEnvironment 服務中預設提供對 Development、Production、Staging 三種環境進行判斷的擴展方法,如果是其他自定的環境,如 Test,可以使用 IsEnviroment() 方法進行判斷。

image

  通過 IWebHostEnvironment 判斷不同環境,從而在 StartUp 類中使用不同的初始化初始化邏輯,這種方式適合於不同環境下代碼差異較少的情況。除此之外還有兩種基於約定的方式,分別是 Startup 方法約定 和 StartUp 類名約定 。

  StartUp 方法約定具體是指 StartUp 類中 ConfigureServices 和 Configure 方法還可以按照Configure{EnvironmentName}Services和Configure{EnvironmentName}Services 這樣的命名格式來寫,通過命名約定的 {EnvironmentName} 部分區分不同環境,裝載不同環境的代碼。

  如果 StartUp 類中存在與當前環境名稱匹配的 Configure{EnvironmentName}Services和Configure{EnvironmentName}Services 方法的話,則應用啟動時會執行相應的方法中的邏輯,如果沒有則執行原始的 ConfigureServices 和 Configure 方法中的邏輯。

image

  通過查看源碼,可以看到當我們明確配置一個 Startup 類作為應用啟動類的時候,會先判斷是否是實現了 IStartup 介面。

image

  如果沒有的話,則通過 StartupLoader 判斷 Startup 類是否符合約定,最終構建出實現了 IStartup 介面的ConventionBasedStartup,並註入到容器中。這時候會結合環境變數,優先獲取帶有環境變數的方法,如果沒有則使用沒有帶環境變數的方法。

image
image
image

  而 StartUp 類名約定和方法約定類似,程式啟動時,會優先尋找當前環境命名符合Startup{EnvironmentName}的 Startup 類,如果找不到,則使用名稱為Startup的類。類名約定的方式適用於多環境下,代碼差異較大的情況。

image

  類名約定的方式下,在配置使用 UseStartUp 的時候需要一點小改動:
image

  查看源碼,可以看到在我們調用上面的方法的時候,實際上並沒有做具體的 Startup 類的構建操作,只是寫入了兩個設置,其實就是寫入到了配置系統中,其中 WebHostDefaults.StartupAssemblyKey 是關鍵。

image

image

  之後在我們應用啟動,調用Build方法時,在構建ASP.NET Core 基本服務的時候才會根據設置去構建啟動類。

image

image

image

  在這裡通過 StartupLoader 結合環境名稱查找程式集中符合約定的 Startup 類。



參考文章:

理解ASP.NET Core - Startup

ASP.NET CORE 3.1 — 應用啟動



ASP.NET Core 系列總結:

目錄:ASP.NET Core 系列總結
下一篇:ASP.NET Core - IStartupFilter與IHostingStartup


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 對於Python新手來說,寫代碼很少考慮代碼的效率和簡潔性,因此容易造成代碼冗長、執行慢,這些都是需要改進的地方。本文是想通過幾個案列給新手一點啟發,怎樣寫python代碼更優雅。 大坑一:不喜歡使用高級數據結構 1.sets(集合) 很多新手忽視sets(集合)和tuple(元組)的強大之處 例如 ...
  • Spring Cloud Gateway 是 Spring Cloud 的一個全新項目,該項目是基於 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等響應式編程和事件流技術開發的網關,它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式。① 身... ...
  • 1.gensim的安裝 可以使用如下命令安裝gensim conda install -i https://pypi.tuna.tsinghua.edu.cn/simple gensim==3.8.2 2.生成分詞列表 這一步已經有生成好的分詞列表可以忽略 項目列表: 點擊查看代碼 # coding ...
  • 各位技術大佬,大家好,我是練習時長兩年半的代碼練習生,Max,喜歡技術,後端和架構。 問題介紹 項目配置了多個功能變數名稱,如下,php 代碼中有獲取 $_SERVER['SERVER_NAME'] 的值。 server { server_name a.demo.com b.demo.com; ... } ...
  • 《Terraform 101 從入門到實踐》這本小冊在南瓜慢說官方網站和GitHub兩個地方同步更新,書中的示例代碼也是放在GitHub上,方便大家參考查看。 介紹了Terraform一些比較基礎的概念後,我們可以先瞭解一下Terraform的語法,也就是HCL的語法。 變數Variables 變數 ...
  • chatGPT最近突然又大火起來了,而且這次不是一般的火,帶有濃濃的商業氣息火了。各個互聯網大廠都開始進軍了,感覺要來一場ChatGPT的軍備競賽一樣,看看誰先獲取國內的地盤。 作為吃瓜群眾,我們也能個人使用ChatGPT,現在小捲來教大家更高級的玩法,就是用個人微信接入ChatGPT,個人微信變... ...
  • FASTJSON2項目使用了上面的技巧,其中JDKUtils和UnsafeUtils有上面技巧的實現: JDKUtils:https://github.com/alibaba/fastjson2/blob/fastcode_demo_20221218/core/src/main/java/com/... ...
  • 準備工作 Docker環境 Mongo資料庫 配置Mongo資料庫 ASP.NET6 集成Mongo 安裝MongoDB.Driver { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Wa ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...