# `Asp.Net Core` 組態設定 ## 舊版寫法 **組態設定**由**設定提供者**(Configuration Providers)負責 + 從命令列參數(Command Line Arguments)取得組態設定 (docker) + 從**環境變數**(Environment Variables)取得組態設定 (單體式服務推薦使用環境變數設置組態) + 開發時期可以從**Secret Manager**儲存區取得設定 + JSON file (appsetting.json) 組態設定最終都會變成 Key-Value paris 的形式 + 所有的 Key 與 Value 一定是「字串」型別 + 組態設定很容易被反序列列化成任何 POCO 物件 + 組態設定使用 IConfiguration 型別的物件取得設定值 appsetting.json ```json! { "Appsettings": { "Name": "Staging", "SmtpSettings": { "SmtpIp": "smtp.gmail.com", "SmtpPort": "587", } }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } } } ``` 建立一個組態設定對應類別 ```csharp! public class AppSettings { public string Name {get; set;} public SmtpSettings SmptSettings {get; set;} } public class SmtpSettings { public string? SmtpIp {get; set;} public int SmtpPort {get; set;} } ``` 在 Program.cs 中註冊 ```csharp! builder.Services.Configure<AppSettings>( // 此處是向 Asp.Net Core 的組態管理索取 AppSettings 的區段 // 與 appsettings.json 沒有直接關係 // builder.Configuration.GetSection 是抽象的操作 // 具體的行為由各類 Provider 實作 builder.Configuration.GetSection("AppSettings") // 只要綁定 AppSettings 組態部分,下面的 SmtpOptions 就會自動綁定到對應的類別 ); ``` 在需要依賴組態設定的物件中注入 ```csharp! public IOptions<AppSettings> Settings {get;} public ValuesController(IOptions<AppSettings> options) { Settings = options; } public IActionRestult<int> Do() { var smtpPort = Settings.Value.SmtpSettings.SmtpPort; return smtpPort; } ``` 生產環境建議使用**環境變數**設置組態 ```shell! set AppSettings__SmtpIp=smtp.hinet.net ``` ```csharp! builder.Configuration.AddEnvironmentVariables("FSE_"); #region OptionSettings builder.Services.Configure<AppSettings>( builder.Configuration.GetSection(nameof(AppSettings)) ); #endregion ``` + 環境變數 | 變數 | 值 | | ---------------------------------------- | ---------------------------------------------------------------------------------- | | FSE_AppSettings__Env | Stage | | FSE_ConnectionStrings__DefaultConnection | Server=.;Database=BcryptDemo;Trusted_Connection=True;MultipleActiveResultSets=true | | FSE_AppSettings__SmtpOptions__Server | smtp.yahoo.com | | FSE_AppSettings__SmtpOptions__Port | 5001 | + 在需要讀取配置的地方,建議使用 `IOptionsSnapshot<T>` 注入,當檔案型的組態設置(例如: appsettings.json)變更時,可以即時更新。 (補充: 環境變數配置的組態設定就必須要重新啟動程式) + 將敏感訊息(例如: 連線字串)寫到環境變數中,降低機密洩漏風險。 ## 新版寫法 > [參考](https://blog.miniasp.com/post/2024/05/06/net-7-net-generic-host)