1. 程式人生 > >翻譯 - ASP.NET Core 基本知識 - 配置(Configuration)

翻譯 - ASP.NET Core 基本知識 - 配置(Configuration)

翻譯自 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-5.0

ASP.NET Core 中的配置使用一個或者多個配置提供程(configuration providers)序實現。配置提供程式從多種鍵值對中的配置源中讀取配置資料:

  • 設定檔案,例如 appsetting.json
  • 環境變數
  • Azure 鍵庫
  • Azure App 配置
  • 命令列引數
  • 自定義提供器,安裝的或者建立的
  • 目錄檔案
  • 記憶體中的 .NET 物件

本話題提供 ASP.NET Core 中關於配置的資訊。更多關於在控制檯應用程式中使用配置的資訊,檢視 .NET Configuration.

預設配置

使用 dotnet new 或者 Visual Studio 建立的 ASP.NET Core 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>();
            });
}

CreateDefaultBuilder 按照以下順序為應用程式提供預設配置:

  1. ChainedConfigurationProvider:新增一個現存的 IConfiguration 作為一個源。在一個預設配置例子中,新增主機(host)配置並且設定它作為第一個應用程式配置的源。
  2. appsettings.json 使用 JSON 配置提供器(JSON configuration provider)。
  3. appsetttings.Environment.json 使用 JSON 配置提供器(JSON configuration provider)。例如,appsettings.Production.json 和 appsettings.Developments.json。
  4. App secrets,當應用程式執行在開發 (Development) 環境中。
  5. 環境變數使用  Environment Variables configuration provider。
  6. 命令列引數使用 Command-line configuration provider。

後新增的配置提供器會覆蓋先前新增的鍵值設定。例如,如果 MyKey 同事在 appsettings.json 和 環境變數中設定,環境變數的值將會被使用。如果使用預設的配置提供器,命令列配置提供器(Command-line configuration provider) 將會覆蓋所有的提供器。

關於 CreateDefaultBuilder 的更多資訊,檢視 Default builder settings。

下面的程式碼展示了使能的配置提供器的新增順序:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

appsettings.json

考慮下面的 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey":  "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

示例 (sample download) 中的程式碼展示了幾個上面的配置設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

預設的 JsonConfigurationProvider 按照以下順序載入配置:

1. appsettings.json

2. appsettings.Environment.json:例如,appsettings.Production.json 和 appsettings.Development.json 檔案。檔案的環境版本基於 IHostingEnvironment.EnvironmentName,更多資訊,檢視 Use multiple environments in ASP.NET Core.

appsettings.Environment.json 中的值會覆蓋 appsettings.json 中的值。例如,預設的:

  • 在開發環境中,appsettings.Development.json 配置會覆蓋 appsettings.json 中存在的值
  • 在生產環境中,appsettings.Production.json 的配置會覆蓋 appsettings.json 中存在的值,例如,當部署應用程式到 Azure 上的時候。

使用選項模型繫結繼承配置資料

讀取相關配置值的推薦方式是使用選項模型 (options pattern)。例如,讀取下面的配置值:

"Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

建立 PositionOptions 類:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; }
    public string Name { get; set; }
}

一個選項類:

  • 必須是帶有公共無引數的構造方法的非抽象類
  • 所有公共的可讀寫的屬性型別要被繫結
  • 欄位沒有繫結。在前面的程式碼中,Position 沒有繫結。使用 Position 屬性,因此字串 "Position" 就不用在繫結類到一個配置提供器的時候硬編碼在應用程式中

下面的程式碼:

  • 呼叫 ConfigurationBinder.Bind 繫結 PositionOptions 類到 Position 區域
  • 展示 Position 配置資料
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

在上面的程式碼中,預設的,在應用程式啟動後對於 JSON 配置檔案的改變也會被讀取到。

ConfigurationBinder.Get<T> 繫結和返回指定的型別。ConfigurationBinder.Get<T> 可能比使用 ConfigurationBinder.Bind 更方便。下面的程式碼展示瞭如何使用 ConfigurationBinder.Get<T> 使用 PositionOptions 類:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

預設的,上面的程式碼會讀取到在應用程式啟動後對於 JSON 配置檔案的更改。

使用 options patter 的一種方法是繫結 Position 區域並且新增到依賴注入服務容器 (dependency injection service container) 中。下面的程式碼中,PositionOptions 在 Configure 中被新增到服務容器中,並繫結到配置:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(Configuration.GetSection(
                                        PositionOptions.Position));
    services.AddRazorPages();
}

使用了上面的程式碼,下面的程式碼讀取 position options:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

上面的程式碼在應用程式啟動後不會讀取到對 JSON 配置檔案的更改。如果要讀取應用程式啟動後的更改,可以使用 IOptionsSnapshot。

使用預設(default)的配置,appsettings.json 和 appsettings.Environment.json 檔案使能了  reloadOnChange: true 。在應用程式啟動後對 appsettings.json 和 appsettings.Environment.json 的更改會被 JSON configuration provider 讀取到。

檢視本文件中 JSON configuration provider 關於新增更多 JSON 配置檔案的資訊。

合併服務集合

考慮下面的 ConfigureServices 方法,其中註冊服務和配置選項:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(
        Configuration.GetSection(PositionOptions.Position));
    services.Configure<ColorOptions>(
        Configuration.GetSection(ColorOptions.Color));

    services.AddScoped<IMyDependency, MyDependency>();
    services.AddScoped<IMyDependency2, MyDependency2>();

    services.AddRazorPages();
}

相關的一組的註冊可以被移動到擴充套件方法中去註冊服務。例如,配置服務被新增到下面的類中:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }
    }
}

其餘的服務在一個相似的類中被註冊。下面的 ConfigureServices 方法使用的新的擴充套件方法註冊服務:

public void ConfigureServices(IServiceCollection services)
{
    services.AddConfig(Configuration)
            .AddMyDependencyGroup();

    services.AddRazorPages();
}

備註:每一個 services.Add{GROUP_NAME} 擴充套件方法新增和潛在的會配置服務。例如,AddControllersWithViews 新增帶有檢視的 MVC 控制器的服務,AddRazorPages 新增帶有 Razor Pages 的服務。我們推薦應用程式遵守命名的約定。把擴充套件方法統一放到名稱空間 Microsoft.Extensions.DependencyInjection 中去封裝一組服務的註冊。

安全和使用者祕密

資料配置指導:

  • 永遠不要把密碼或者其他敏感資料使用配置提供器儲存在程式碼中或者儲存在文字配置檔案中。在開發過程中,可以使用 Secret Manager 工具儲存祕密資料
  • 不要在開發環境或者測試環境中使用生產環境的祕密資料
  • 在工程外部指定祕密資料,以防被意外的提交到原始碼倉庫中

預設的,使用者祕密配置源是在 JSON 配置源之後註冊的。因此,使用者祕密的鍵值會生效,而不是 appsettings.json 和 appsettings.Environment.json 中的鍵值。

更多關於儲存密碼或者其他敏感資料的資訊:

  • Use multiple environments in ASP.NET Core
  • Safe storage of app secrets in development in ASP.NET Core:包含關於使用環境變數儲存敏感資料的建議。祕密管理工具使用 File configuration provider 在本地系統上儲存使用者密碼在一個 JSON 檔案

Azure Key Vault 為 ASP.NET Core 應用程式安全的儲存應用程式的祕密。更多資訊檢視 Azure Key Vault Configuration Provider in ASP.NET Core。

環境變數

使用預設的配置,EnvironmentVariablesConfigurationProvider 在讀取 appsettings.json,appsettings.Environment.json,和 user secrets 之後從環境變數載入鍵值對。因此,從環境變數讀取到的鍵值會覆蓋從 appsettings.json, appsettings.Environment.json 和 user secrets 中讀取到的值。

: 分隔符在所有平臺上對於環境便令分級鍵都是不工作的。__ 雙下換線:

  • 所有平臺都支援。例如, Bash 不支援 : 分隔符,但是支援 __
  • 會自動的被一個 : 替換

下面的設定命令:

  • 在 Windows 上設定前面示例(preceding exampl)中的環境鍵值和值
  • 使用示例程式(sample download)測試設定。dotnet run 命令必須在工程目錄中執行
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

上面的環境變數設定:

  • 僅僅在設定他們的命令列視窗中啟動的程序中
  • 不會被使用 Visual Studio 啟動的瀏覽器讀取

下面的  setx 命令可以被用來在 Windows 上設定環境鍵和值。不同於 set,setx 是持久化的。/M 在系統環境設定變數。如果沒有使用 /M 開關,一個使用者的環境變數會被設定。

setx MyKey "My key from setx Environment" /M
setx Position__Title Setx_Environment_Editor /M
setx Position__Name Environment_Rick /M

為了測試上面的命令會覆蓋 appsettings.json 和 asppsettings.Environment.json 的配置,需要做以下操作:

  • 使用 Visual Studio: 退出和重啟 Visual Studio
  • 使用命令列:啟動一個新的命令視窗,輸入 dotnet run

呼叫 AddEnvironmentVariables,使用一個字串指定環境變數的字首:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在上面的程式碼中:

  • config.AddEnvironmentVariables(prefix: "MyCustomPrefix_") 在預設配置提供器 (default configuration providers) 之後新增。關於配置提供器順序的示例,檢視 JSON 配置提供器 (JSON configuration provider)。
  • 使用 MyCustomPrefix_ 字首設定的環境變數覆蓋了預設配置提供器 (default configuration providers)。這包括沒有字首的環境變數。

當配置鍵值對被讀取的時候,字首會被去除。

下面的命令測試自定義字首:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

預設配置 (default configuration) 載入帶有字首為 DOTNET_ 和 ASPNETCORE_ 的環境變數和命令列引數。DOTNET_ 和 ASPNETCORE_ 字首被 ASP.NET Core 用來配置主機和應用程式配置 (host and app configuration),不能用來作為使用者配置。更多關於主機和應用程式的配置,檢視 .NET Generic Host。

關於  Azure App Service,在設定 (Settings) > 配置 (Configuration) 頁面選擇 新建應用程式設定 (New application setting)。Azure 應用程式服務設定:

  • 在休息是加密,並通過加密通道傳輸
  • 暴露為環境變數

更多資訊,檢視 Azure Apps: Override app configuration using the Azure Portal。

檢視 Connection string prefixes 瞭解關於 Azure 資料庫連線字串的資訊。

 環境變數命名

環境變數的命名反映了 appsettings.json 檔案的結構。層級中的每一個元素使用雙下劃線(推薦的)或者冒號分割開來。當一個元素的結構包含一個數組的時候,陣列的索引應該被當做是當前路徑中的一個額外的元素名稱。考慮下面的 appsettings.json 檔案和它在環境變數中等價的值。

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "[email protected]",
                "ToAddress": "[email protected]"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

環境變數 (environment variables)

setx SmtpServer=smtp.example.com
setx Logging__0__Name=ToEmail
setx Logging__0__Level=Critical
setx [email protected]
setx [email protected]
setx Logging__1__Name=ToConsole
setx Logging__1__Level=Information

生成的 launchSettings.json 檔案中環境變數的設定

在 launchSettings.json 中設定的環境變數會覆蓋那些在系統環境中設定的值。例如,ASP.NET Core web 模板會生成一個 lauchSettings.json 檔案,檔案中設定了

endpoint 配置:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

對 applicationUrl 的配置設定環境變數 ASPNETCORE_URLS  並覆蓋環境中的值。

Escape environment variables on Linux

在 linux 上,URL 環境變數的值必須被 escape 後系統才能夠解析它。使用 linux systemd-escape 工具生成 http:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

顯示環境變數

下面的程式碼在應用程式啟動的時候輸出顯示了環境變數和對應的值,在除錯環境設定的時候非常有用:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var config = host.Services.GetRequiredService<IConfiguration>();

    foreach (var c in config.AsEnumerable())
    {
        Console.WriteLine(c.Key + " = " + c.Value);
    }
    host.Run();
}

命令列

使用預設的配置,CommandLineConfigurationProvider 在下列配置源之後從命令列引數鍵值對中載入配置:

  • appsettings.json 和 appsettings.Environment.json 檔案
  • 開發環境中的 App secrets
  • 環境變數

預設的,在命令列中配置的值會覆蓋其它所有配置提供的值。

命令列引數

下面的命令使用 = 設定鍵和值:

dotnet run MyKey="My key from command line" Position:Title=Cmd Position:Name=Cmd_Rick

下面的命令使用 / 設定鍵值:

dotnet run /MyKey "Using /" /Position:Title=Cmd_ /Position:Name=Cmd_Rick

下面的命令使用 -- 設定鍵值:

dotnet run --MyKey "Using --" --Position:Title=Cmd-- --Position:Name=Cmd--Rick

鍵值:

  • 必須緊跟 = ,或當值在一個空格後面的時候,鍵必須有個 -- 或者 / 字首
  • 當使用 = 的時候,值不是必須要有的,例如 MySetting=

在相同的命令列中,不要把使用 = 的鍵值對和使用空格的鍵值對的命令列引數混淆。

轉換對映

切換對映允許鍵名替換邏輯。可以給 AddCommandLine 方法提供一個切換替換的字典。

當切換對映字典被用到的時候,字典被用來檢查匹配命令列引數提供的鍵。日過命令列的鍵在字典中被找到,字典中的值就會被傳回用來設定應用程式配置的鍵值對。切換對映要求任何的命令列鍵使用一個單獨的破折號作為字首。

切換對映字典鍵的規則:

  • 切換必須以 - 或者 -- 開頭
  • 切換對映字典不能包含重複的鍵

 

使用一個切換對映字典,需要把它傳遞給 AddCommandLine 方法:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddCommandLine(args, switchMappings);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

下面的程式碼展示了被替換的鍵的值:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

下面的命令用來測試鍵替換:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

對於使用切換對映的應用程式,呼叫 CreateDefaultBuilder 不應該傳遞引數。CreateDefaultBuilder 方法的 AddCommandLine 的呼叫不包括對映切換,沒有方法可以傳遞切換對映的字典給 CreateDefaultBuilder。解決方法是允許 ConfigurationBuilder 方法的 AddCommandLine 同時處理引數和切換對映字典而不是傳遞引數給 CreateDefaultBuilder。

分層配置資料

配置 API 通過使用在配置鍵中的分界符扁平化分層資料來讀取配置資料。

示例程式 (sample download) 包含下面的 appsettings.json 檔案:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey":  "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

下面示例 (sample download) 中的程式碼展示了一些配置設定:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

讀取分層配置資料的首選方式是使用選項模型。更多資訊,檢視本文件中的繫結分層配置資料 (Bind hierarchical configuration data)。

GetSection 和 GetChildren 方法可以用來分離配置資料中的分割槽和分割槽中的子部分。這些方法在之後的 GetSection, GetChildren, and Exists 中會描述到。

配置的鍵和值

配置的鍵:

  • 不區分大小寫。例如 ConnectionString 和 connectionstring 被認為是等價的鍵
  • 如果一個鍵和值在多個配置提供器中被設定,最後一個提供器的值將會被使用。更多資訊,檢視預設配置 (Default configuration)
  • 分層鍵
    - 在配置 API 內部,一個冒號分隔符 (:) 在所有平臺都能工作
    - 在環境變數中,一個冒號分隔符可能不會在所有平臺上工作。雙下劃線 (__) 被所有平臺支援,並且會被自動的轉換為一個冒號 (:)
    - 在 Azure 鍵倉庫中,分層的鍵使用 -- 作為一個分隔符。當祕密資料被載入到應用程式配置的時候,Azure Key Vault configuration provider 自動使用一個冒號 (:) 替換 (--)。
  • ConfigurationBinder 支援繫結陣列到在配置鍵中使用陣列索引的物件。陣列繫結在 Bind an array to a class 部分描述。

配置值:

  • 是字串
  • Null 值不能儲存在配置中或者繫結到物件

配置提供器

下面的表格中顯示了 ASP.NET Core 應用程式中可以使用的配置提供器

Provider Providers configuration from
Azure Key Vault configuration provider Azure Key Valut
Azure App configuration provider Azure App Configuration
Command-line configuration provider Command-line parameters
Custom configuration provider Custom source
Environment Variables configuration provider Environment variables
File configuration provider INI,JSON,XML 檔案
Key-per-file configuration provider 字典檔案
Memory configuration provider 記憶體中的集合
User secrets 使用者配置目錄中的檔案

配置源的讀取的順序按照它們的配置提供器被指定的順序。在程式碼中對配置提供器排序來滿足應用程式要求的配置源的順序。

一個典型的配置提供器的順序是:

  1. appsettings.json
  2. appsettings.Environment.json
  3. User secrets
  4. 使用 Environment Variables configuration provider 的環境變數
  5. 使用 Command-line configuration provider 的命令列引數

一個常用的實踐是在一系列的配置提供器的最後新增命令列配置提供器,用來覆蓋其它提供器的配置設定

上面的提供器的順序在預設配置 (default configuration) 中使用。

連線字串字首

配置 API 對於四種連線字串環境變數有特殊的處理規則。這些連線字串會根據應用程式環境解析來配置 Azure 連線字串。下面表格中的帶有字首的環境變數在應用程式使用預設配置 (default configuration)或者沒有字首沒有應用到 AddEnvironmentVariables 的情況下會被載入到應用程式中。

Connection string prefix Provider
CUSTOMCONNSTR_ 自定義提供器
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

當一個環境變數被發現並且使用表格中四種字首的任一種被載入到配置中的時候:

  • 通過移除環境變數的字首建立配置的鍵,新增一個配置鍵的區域(ConnectionStrings)
  • 一個新的配置的鍵值對被建立,這個鍵值對代表了資料庫連線提供器 (CUSTOMCONNSTR_ 除外,由於沒有固定的提供器)
環境變數鍵 轉換後的配置鍵 提供器配置入口
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 配置入口沒有建立
MYSQLCONNSTR_{KEY} ConnectionString:{KEY}

Key:ConnectionStrings:

{KEY}_ProviderName:

Value:MySql.DataMySqlClient

SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY}

Key:ConnectionStrings:

{KEY}_ProviderName:

Value:System.Data.SqlClient

SQLCONNSTR_{KEY} ConnectionStrings:{KEY}

Key:ConnectionStrings:

{KEY}_ProviderName:

Value:System.Data.SqlClient

 檔案配置提供器

FileConfigurationProvider 是從檔案系統載入配置的基類。下面的配置提供器都從 FileConfigurationProvider 類繼承而來。

  • INI configuration provider
  • JSON configuration provider
  • XML configuration provider

INI 配置提供器

IniConfigurationProvider 在執行時從 INI 檔案中載入鍵值對的配置。

下面的程式碼清空了所有配置提供器,添加了一些配置提供器:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
                      .AddIniFile($"MyIniConfig.{env.EnvironmentName}.ini",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

&n