.NET 中的組態是使用一或多個 組態提供者來執行,。 設定提供者使用各種設定來源,從鍵值對讀取設定資料。
- 配置檔案,例如 appsettings.json
- 環境變數
- Azure 密鑰保管庫
- Azure 應用程式組態
- 命令列參數
- 自訂提供者,已安裝或建立
- 目錄檔案
- 記憶體內部 .NET 物件
- 第三方提供者
注意
如需設定 .NET 執行時間本身的相關信息,請參閱 .NET 執行時間組態設定。
概念和抽象概念
假設有一或多個組態來源,IConfiguration 類型會提供組態數據的統一檢視。 組態是只讀的,而且設定模式的設計不是以程式設計方式可寫入的。
IConfiguration 介面是所有組態來源的單一表示法,如下圖所示:
設定主控台應用程式
根據 預設,使用 dotnet new 命令範本或 Visual Studio 建立的 .NET 控制台應用程式不會 公開組態功能。 若要在新的 .NET 控制台應用程式中新增組態,將套件參考 新增至 Microsoft.Extensions.Configuration。 此套件是 .NET 應用程式中設定的基礎。 它提供 ConfigurationBuilder 和相關類型。
using Microsoft.Extensions.Configuration;
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>()
{
["SomeKey"] = "SomeValue"
})
.Build();
Console.WriteLine(configuration["SomeKey"]);
// Outputs:
// SomeValue
上述程式代碼:
- 建立新的 ConfigurationBuilder 實例。
- 將索引鍵/值組的記憶體內部集合新增至組態產生器。
- 呼叫 Build() 方法來建立 IConfiguration 實例。
- 將
SomeKey鍵的值寫入控制台。
雖然此範例使用記憶體內部組態,但有許多可用的組態提供者,並公開檔案型、環境變數、命令行自變數和其他組態來源的功能。 如需詳細資訊,請參閱 .NET 中的組態提供者。
替代託管方法
通常,您的應用程式不僅僅是用來讀取設定。 他們可能會使用相依性注入、日誌記錄和其他服務。 針對使用這些服務的應用程式,建議使用 .NET 泛型主機 方法。 相反地,請考慮將套件參考新增至Microsoft.Extensions.Hosting。 修改 Program.cs 檔案,以符合下列程序代碼:
using Microsoft.Extensions.Hosting;
using IHost host = Host.CreateApplicationBuilder(args).Build();
// Application code should start here.
await host.RunAsync();
Host.CreateApplicationBuilder(String[]) 方法會依下列順序提供應用程式的預設組態,從最高優先順序到最低優先順序:
- 使用 命令列組態提供者的命令列引數。
- 使用環境變數組態提供者 的環境變數。
-
應用程式秘密 當應用程式在
Development環境中執行時。 -
appsettings.
Environment.json 使用 JSON 設定提供者。 例如,appsettings。Production。json 和 appsettings。Development。json。 - appsettings.json 使用 JSON 組態提供者。
-
ChainedConfigurationProvider:將現有的
IConfiguration新增為來源。
新增設定提供程式會覆寫先前的組態值。 例如,命令列組態提供者 會覆寫其他提供者的所有值,因為它是最後添加的。 如果在 SomeKey 和環境中設定 ,則會使用環境值,因為已在 appsettings.json之後新增它。
捆綁
使用 .NET 組態抽象概念的其中一個主要優點是能夠將組態值系結至 .NET 對象的實例。 例如,JSON 組態提供者可用來將 appsettings.json 檔案對應至 .NET 物件,並與 相依性插入搭配使用。 這可讓 選項設計模式,並且此模式使用類別來提供強型別存取,允許存取相關的設定群組。 默認系結器是基於反射的,但還有一個易於啟用的 來源產生器替代方案。
.NET 組態提供各種抽象概念。 請考慮下列介面:
- IConfiguration:代表一組鍵/值的應用程式配置屬性。
-
IConfigurationRoot:代表
IConfiguration階層的根基。 - IConfigurationSection:代表應用程式組態值的區段。
這些抽象概念與其基礎組態提供者無關(IConfigurationProvider)。 換句話說,您可以使用 IConfiguration 實例,從多個提供者存取任何組態值。
系結器可以使用不同的方法來處理組態值:
- 基本型別的直接反序列化,使用內建轉換器。
- 當類型存在一個複雜型別時,其複雜型別的 TypeConverter。
- 具有屬性之複雜類型的反映。
注意
系結器有一些限制:
- 如果屬性具有 private 設定器,或其類型無法轉換,則會忽略該屬性。
- 忽略沒有對應組態索引鍵的屬性。
系結階層
組態值可以包含階層式數據。 階層式物件會使用組態索引鍵中的 : 分隔符來表示。 若要存取組態值,請使用 : 字元來分隔階層。 例如,請考慮下列組態值:
{
"Parent": {
"FavoriteNumber": 7,
"Child": {
"Name": "Example",
"GrandChild": {
"Age": 3
}
}
}
}
下表代表上述範例 JSON 的範例索引鍵及其對應的值:
| 鑰匙 | 價值 |
|---|---|
"Parent:FavoriteNumber" |
7 |
"Parent:Child:Name" |
"Example" |
"Parent:Child:GrandChild:Age" |
3 |
基本範例
若要以基本形式存取組態值,如果沒有 一般主機 方法的協助,請直接使用 ConfigurationBuilder 類型。
提示
System.Configuration.ConfigurationBuilder 類型與 Microsoft.Extensions.Configuration.ConfigurationBuilder 類型不同。 此內容全都專屬於 Microsoft.Extensions.* NuGet 套件和命名空間。
請考慮下列 C# 專案:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.0" />
</ItemGroup>
</Project>
前面的專案檔參考了數個 NuGet 組態套件:
-
Microsoft.Extensions.Configuration.Binder:將對象系結至
Microsoft.Extensions.Configuration組態提供者中的數據的功能。 -
Microsoft.Extensions.Configuration.Json:適用於
Microsoft.Extensions.Configuration的 JSON 組態提供者實作。 -
Microsoft.Extensions.Configuration.EnvironmentVariables:
Microsoft.Extensions.Configuration的環境變數組態提供者實作。
請考慮範例 appsettings.json 檔案:
{
"Settings": {
"KeyOne": 1,
"KeyTwo": true,
"KeyThree": {
"Message": "Oh, that's nice...",
"SupportedVersions": {
"v1": "1.0.0",
"v3": "3.0.7"
}
},
"IPAddressRange": [
"46.36.198.121",
"46.36.198.122",
"46.36.198.123",
"46.36.198.124",
"46.36.198.125"
]
}
}
現在,假設此 JSON 檔案,以下是直接使用組態產生器的範例取用模式:
using Microsoft.Extensions.Configuration;
// Build a config object, using env vars and JSON providers.
IConfigurationRoot config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.Build();
// Get values from the config given their key and their target type.
Settings? settings = config.GetRequiredSection("Settings").Get<Settings>();
// Write the values to the console.
Console.WriteLine($"KeyOne = {settings?.KeyOne}");
Console.WriteLine($"KeyTwo = {settings?.KeyTwo}");
Console.WriteLine($"KeyThree:Message = {settings?.KeyThree?.Message}");
// Application code which might rely on the config could start here.
// This will output the following:
// KeyOne = 1
// KeyTwo = True
// KeyThree:Message = Oh, that's nice...
上述 C# 程式代碼:
- 創建一個 ConfigurationBuilder。
- 添加
"appsettings.json"檔案以供 JSON 組態提供者辨識。 - 將環境變數新增以供環境變數組態提供者辨識。
- 使用
"Settings"實例,取得所需的Settings區段和相應的config實例。
Settings 物件的形狀如下:
public sealed class Settings
{
public required int KeyOne { get; set; }
public required bool KeyTwo { get; set; }
public required NestedSettings KeyThree { get; set; } = null!;
}
public sealed class NestedSettings
{
public required string Message { get; set; } = null!;
}
主機託管的基本範例
若要存取 IConfiguration 值,您可以再次依賴 Microsoft.Extensions.Hosting NuGet 套件。 建立新的主控台應用程式,並將下列專案檔內容貼到其中:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
</ItemGroup>
</Project>
上述項目檔會定義:
- 應用程式是可執行檔。
- 編譯專案時,appsettings.json 檔案會複製到輸出目錄。
- 已新增
Microsoft.Extensions.HostingNuGet 套件參考。
使用下列內容,在專案的根目錄中新增 appsettings.json 檔案:
{
"KeyOne": 1,
"KeyTwo": true,
"KeyThree": {
"Message": "Thanks for checking this out!"
}
}
使用下列 C# 程式代碼取代 Program.cs 檔案的內容:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using IHost host = Host.CreateApplicationBuilder(args).Build();
// Ask the service provider for the configuration abstraction.
IConfiguration config = host.Services.GetRequiredService<IConfiguration>();
// Get values from the config given their key and their target type.
int keyOneValue = config.GetValue<int>("KeyOne");
bool keyTwoValue = config.GetValue<bool>("KeyTwo");
string? keyThreeNestedValue = config.GetValue<string>("KeyThree:Message");
// Write the values to the console.
Console.WriteLine($"KeyOne = {keyOneValue}");
Console.WriteLine($"KeyTwo = {keyTwoValue}");
Console.WriteLine($"KeyThree:Message = {keyThreeNestedValue}");
// Application code which might rely on the config could start here.
await host.RunAsync();
// This will output the following:
// KeyOne = 1
// KeyTwo = True
// KeyThree:Message = Thanks for checking this out!
當您執行此應用程式時,Host.CreateApplicationBuilder 會定義探索 JSON 組態的行為,並透過 IConfiguration 實例公開。 從 host 實例中,您可以向服務提供者詢問 IConfiguration 實例,然後詢問它的值。
提示
以這種方式使用原始 IConfiguration 實例,雖然方便,但擴展性不好。 當應用程式變得複雜度增加,且其對應的組態變得更複雜時,建議您使用 選項模式 作為替代方案。
裝載和使用索引器 API 的基本範例
請考慮上述範例中的相同 appsettings.json 檔案內容:
{
"SupportedVersions": {
"v1": "1.0.0",
"v3": "3.0.7"
},
"IPAddressRange": [
"46.36.198.123",
"46.36.198.124",
"46.36.198.125"
]
}
使用下列 C# 程式代碼取代 Program.cs 檔案的內容:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using IHost host = Host.CreateApplicationBuilder(args).Build();
// Ask the service provider for the configuration abstraction.
IConfiguration config = host.Services.GetRequiredService<IConfiguration>();
// Get values from the config given their key and their target type.
string? ipOne = config["IPAddressRange:0"];
string? ipTwo = config["IPAddressRange:1"];
string? ipThree = config["IPAddressRange:2"];
string? versionOne = config["SupportedVersions:v1"];
string? versionThree = config["SupportedVersions:v3"];
// Write the values to the console.
Console.WriteLine($"IPAddressRange:0 = {ipOne}");
Console.WriteLine($"IPAddressRange:1 = {ipTwo}");
Console.WriteLine($"IPAddressRange:2 = {ipThree}");
Console.WriteLine($"SupportedVersions:v1 = {versionOne}");
Console.WriteLine($"SupportedVersions:v3 = {versionThree}");
// Application code which might rely on the config could start here.
await host.RunAsync();
// This will output the following:
// IPAddressRange:0 = 46.36.198.123
// IPAddressRange:1 = 46.36.198.124
// IPAddressRange:2 = 46.36.198.125
// SupportedVersions:v1 = 1.0.0
// SupportedVersions:v3 = 3.0.7
這些值是使用索引器 API 來存取,其中每個索引鍵都是字串,而值則是字串。 組態支援屬性、物件、陣列和字典。
設定提供者
下表顯示 .NET Core 應用程式可用的組態提供者。
| 供應商 | 提供來自[來源]的組態 |
|---|---|
| Azure 應用程式設定提供者 | Azure 應用程式組態 |
| Azure Key Vault 組態提供者 | Azure Key Vault |
| 命令行組態提供者 | 命令行參數 |
| 自定義組態提供者 | 自訂來源 |
| 環境變數組態提供者 | 環境變數 |
| 檔案組態提供者 | JSON、XML 和 INI 檔案 |
| 每個檔案的金鑰組態提供者 | 目錄檔案 |
| 記憶體設定提供者 | 內存集合 |
| 應用程式密碼 (密碼管理器) | 使用者配置檔目錄中的檔案 |
提示
新增組態提供者的順序很重要。 使用多個組態提供者,且多個提供者指定相同的索引鍵時,會使用最後一個新增的密鑰。
如需各種組態提供者的詳細資訊,請參閱 .NET 中的組態提供者。
另請參閱
- .NET 中的 組態提供者
- 實作自定義組態提供者
- 應該在 github.com/dotnet/runtime 存放庫中建立組態錯誤
- ASP.NET Core 中的 組態