Поставщики конфигурации в .NET

Конфигурацию в .NET можно выполнять с помощью с поставщиков конфигурации. Несколько типов поставщиков используют различные источники конфигурации. В этой статье подробно описаны различные поставщики конфигурации и соответствующие им источники.

Поставщик конфигурации файла

FileConfigurationProvider является базовым классом для загрузки конфигурации из файловой системы. Следующие поставщики конфигурации являются производными от FileConfigurationProvider:

В ключах не учитывается регистр символов. Все поставщики конфигурации файлов создают FormatException повторяющиеся ключи в одном поставщике.

Поставщик конфигурации JSON

Класс JsonConfigurationProvider загружает конфигурацию из JSON-файла. Установите пакет NuGet Microsoft.Extensions.Configuration.Json.

Перегрузки могут указывать:

  • Файл является обязательным или нет.
  • Будет ли перезагружена конфигурация, если файл изменится.

Рассмотрим следующий код:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using ConsoleJson.Example;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

IHostEnvironment env = builder.Environment;

builder.Configuration
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);

TransientFaultHandlingOptions options = new();
builder.Configuration.GetSection(nameof(TransientFaultHandlingOptions))
    .Bind(options);

Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

Предыдущий код:

  • Удаляет всех существующих поставщиков конфигурации, добавленных по умолчанию в метод CreateApplicationBuilder(String[]).
  • Настраивает поставщик конфигурации JSON для загрузки appsettings.json и appsettings.Environment.JSON-файлы со следующими параметрами:
    • optional: true: файл является необязательным.
    • reloadOnChange: true: при сохранении изменений файл перезагружается.

Внимание

При добавлении поставщиков конфигурации с IConfigurationBuilder.Addпомощью добавленный поставщик конфигурации добавляется в конец списка IConfigurationSource . Когда ключи найдены несколькими поставщиками, последний поставщик для чтения ключа переопределяет предыдущих поставщиков.

Ниже приведен пример файла appsettings.json с различными параметрами конфигурации.

{
    "SecretKey": "Secret key value",
    "TransientFaultHandlingOptions": {
        "Enabled": true,
        "AutoRetryDelay": "00:00:07"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    }
}

Из экземпляра IConfigurationBuilder после добавления поставщиков конфигурации можно вызвать IConfigurationBuilder.Build() для получения IConfigurationRoot объекта. Корневой элемент конфигурации представляет корень иерархии конфигурации. Разделы из конфигурации могут быть привязаны к экземплярам объектов .NET и более поздних версий, предоставляемых путем IOptions<TOptions> внедрения зависимостей.

Примечание.

Свойствам Действие сборки и "Копировать в выходной каталог" JSON-файла должны быть заданы значения Содержимое и Копировать более новые (или "Всегда копировать"), соответственно.

Рассмотрим класс TransientFaultHandlingOptions, определенный следующим образом:

namespace ConsoleJson.Example;

public sealed class TransientFaultHandlingOptions
{
    public bool Enabled { get; set; }
    public TimeSpan AutoRetryDelay { get; set; }
}

Следующий код создает корень конфигурации, привязывает раздел к типу класса TransientFaultHandlingOptions и выводит привязанные значения в окно консоли:

TransientFaultHandlingOptions options = new();
builder.Configuration.GetSection(nameof(TransientFaultHandlingOptions))
    .Bind(options);

Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");

Приложение записывает следующие примеры выходных данных:

// Sample output:
//    TransientFaultHandlingOptions.Enabled=True
//    TransientFaultHandlingOptions.AutoRetryDelay=00:00:07

Поставщик конфигурации XML

Класс XmlConfigurationProvider загружает конфигурацию из XML-файла во время выполнения. Установите пакет NuGet Microsoft.Extensions.Configuration.Xml.

Следующий код демонстрирует конфигурацию XML-файлов с помощью поставщика конфигурации XML.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

builder.Configuration
    .AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true)
    .AddXmlFile("repeating-example.xml", optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();

if (args is { Length: > 0 })
{
    builder.Configuration.AddCommandLine(args);
}

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

Предыдущий код:

  • Удаляет всех существующих поставщиков конфигурации, добавленных по умолчанию в метод CreateApplicationBuilder(String[]).
  • Настраивает поставщик конфигурации XML для загрузки appsettings.xml и repeating-example.xml файлов со следующими параметрами:
    • optional: true: файл является необязательным.
    • reloadOnChange: true: при сохранении изменений файл перезагружается.
  • Настраивает поставщика конфигурации переменных среды.
  • Настраивает поставщик конфигурации командной строки, если указанный args аргумент содержит аргументы.

Параметры XML переопределяются параметрами в поставщике конфигурации переменных среды и поставщике конфигурации командной строки.

Ниже приведен пример файла appsettings.xml с различными параметрами конфигурации:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <SecretKey>Secret key value</SecretKey>
  <TransientFaultHandlingOptions>
    <Enabled>true</Enabled>
    <AutoRetryDelay>00:00:07</AutoRetryDelay>
  </TransientFaultHandlingOptions>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

Совет

Чтобы использовать IConfiguration тип в приложениях WinForms, добавьте ссылку на пакет NuGet Microsoft.Extensions.Configuration.Xml . Создание экземпляров ConfigurationBuilder вызовов и цепочки вызовов AddXmlFile и Build(). Дополнительные сведения см. в статье о проблеме с документацией .NET #29679.

В .NET 5 и более ранних версиях добавьте атрибут name, чтобы различать повторяющиеся элементы, использующие одно имя элемента. В .NET 6 и более поздних версиях поставщик конфигурации XML автоматически индексирует повторяющиеся элементы. Это означает, что вам не нужно указывать атрибут name, кроме случая, когда вам нужен индекс 0 в ключе и есть только один элемент. (При обновлении до .NET 6 или более поздней версии может возникнуть разрыв, полученный из-за этого изменения в поведении. Дополнительные сведения см. в разделе "Повторяющиеся XML-элементы включают индекс".)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

Следующий код считывает предыдущий файл конфигурации и отображает ключи и значения:

IConfigurationRoot configurationRoot = builder.Configuration;

string key00 = "section:section0:key:key0";
string key01 = "section:section0:key:key1";
string key10 = "section:section1:key:key0";
string key11 = "section:section1:key:key1";

string? val00 = configurationRoot[key00];
string? val01 = configurationRoot[key01];
string? val10 = configurationRoot[key10];
string? val11 = configurationRoot[key11];

Console.WriteLine($"{key00} = {val00}");
Console.WriteLine($"{key01} = {val01}");
Console.WriteLine($"{key10} = {val10}");
Console.WriteLine($"{key10} = {val11}");

Приложение запишет следующий пример выходных данных:

// Sample output:
//    section:section0:key:key0 = value 00
//    section:section0:key:key1 = value 01
//    section:section1:key:key0 = value 10
//    section:section1:key:key0 = value 11

Атрибуты можно использовать для предоставления значений.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

Предыдущий файл конфигурации загружает следующие ключи с помощью value.

  • key:attribute
  • section:key:attribute

Поставщик конфигурации INI

Класс IniConfigurationProvider загружает конфигурацию из INI-файла во время выполнения. Установите пакет NuGet Microsoft.Extensions.Configuration.Ini.

Следующий код очищает всех поставщиков конфигурации и добавляет IniConfigurationProvider с двумя INI-файлами в качестве источника:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Configuration.Sources.Clear();

IHostEnvironment env = builder.Environment;

builder.Configuration
    .AddIniFile("appsettings.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"appsettings.{env.EnvironmentName}.ini", true, true);

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

Ниже приведен пример файла appsettings.ini с различными параметрами конфигурации:

SecretKey="Secret key value"

[TransientFaultHandlingOptions]
Enabled=True
AutoRetryDelay="00:00:07"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

Следующий код отображает приведенные выше параметры конфигурации, записывая их в окно консоли:

foreach ((string key, string? value) in
    builder.Configuration.AsEnumerable().Where(t => t.Value is not null))
{
    Console.WriteLine($"{key}={value}");
}

Приложение запишет следующий пример выходных данных:

// Sample output:
//    TransientFaultHandlingOptions:Enabled=True
//    TransientFaultHandlingOptions:AutoRetryDelay=00:00:07
//    SecretKey=Secret key value
//    Logging:LogLevel:Microsoft=Warning
//    Logging:LogLevel:Default=Information

Поставщик конфигурации переменных среды

При использовании конфигурации по умолчанию EnvironmentVariablesConfigurationProvider загружает конфигурацию из пар "ключ-значение" в переменных среды после чтения файлов appsettings.json, appsettings.Environment.json и диспетчера секретов. Поэтому значения ключей, считанные из среды, переопределяют значения, считанные из appsettings.json, appsettings.Environment.json и диспетчера секретов.

Разделитель : не работает с иерархическими ключами переменной среды на всех платформах. Например, : разделитель не поддерживается Bash. Двойной подчеркивание (__), который поддерживается на всех платформах, автоматически заменяет все : разделители в переменных среды.

Давайте рассмотрим класс TransientFaultHandlingOptions:

public class TransientFaultHandlingOptions
{
    public bool Enabled { get; set; }
    public TimeSpan AutoRetryDelay { get; set; }
}

set Следующие команды задают ключи и значения SecretKey среды.TransientFaultHandlingOptions

set SecretKey="Secret key from environment"
set TransientFaultHandlingOptions__Enabled="true"
set TransientFaultHandlingOptions__AutoRetryDelay="00:00:13"

Эти параметры среды задаются только в процессах, запущенных из командного окна, в которых они были заданы. Они не считываются веб-приложениями, запущенными с помощью Visual Studio.

С помощью Visual Studio 2019 и более поздних версий можно указать переменные среды с помощью диалогового окна "Профили запуска".

Launch Profiles dialog showing environment variables

Следующие команды setx можно использовать для задания ключей и значений среды в Windows. В отличие от set, параметры setx сохраняются. /M задает переменную в системной среде. Если параметр /M не используется, задается переменная среды пользователя.

setx SecretKey "Secret key from setx environment" /M
setx TransientFaultHandlingOptions__Enabled "true" /M
setx TransientFaultHandlingOptions__AutoRetryDelay "00:00:05" /M

Чтобы проверить, что предыдущие команды переопределяют любые appsettings.json и appsettings.Environment. Параметры json:

  • С помощью Visual Studio: выход и перезапуск Visual Studio.
  • С помощью интерфейса командной строки: запустите новое командное окно и введите dotnet run.

Префиксы

Чтобы указать префикс для переменных среды, вызовите AddEnvironmentVariables строку:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.AddEnvironmentVariables(prefix: "CustomPrefix_");

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

В предыдущем коде:

  • config.AddEnvironmentVariables(prefix: "CustomPrefix_") добавляется после поставщиков конфигурации по умолчанию. Пример упорядочивания поставщиков конфигурации см. в разделе Поставщик конфигурации XML.
  • Переменные среды, установленные с префиксом CustomPrefix_, переопределяют поставщиков конфигурации по умолчанию. Сюда входят переменные среды без префикса.

Префикс отделяется при создании пары конфигурации "ключ-значение".

Конфигурация по умолчанию загружает переменные среды и аргументы командной строки с префиксом DOTNET_. Префикс DOTNET_ используется .NET для конфигурации узла и приложения, но не для конфигурации пользователя.

Дополнительные сведения о конфигурации узла и приложения см. в разделе Универсальный узел .NET.

Префиксы строк подключения

API конфигурации имеет особые правила обработки для четырех переменных среды строки подключения. Эти строки подключения участвуют в настройке строк подключения Azure для среды приложения. Переменные среды с префиксами, отображаемыми в таблице, загружаются в приложение с конфигурацией по умолчанию или если префикс не предоставляется AddEnvironmentVariables.

Префикс строки подключения Provider
CUSTOMCONNSTR_ Поставщик пользователя
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ База данных SQL Azure
SQLCONNSTR_ SQL Server

Когда переменная среды обнаруживается и загружается в конфигурацию с одним из четырех префиксов, приведенных в таблице, происходит следующее.

  • Ключ конфигурации создается путем удаления префикса переменных среды и добавления ключа раздела конфигурации (ConnectionStrings).
  • Создается новая пара "ключ — значение" конфигурации, которая представляет поставщика подключения базы данных (за исключением CUSTOMCONNSTR_, который не имеет указанного поставщика).
Ключ переменной среды Преобразованный ключ конфигурации Запись конфигурации поставщика
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Запись конфигурации не создана.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Ключ: ConnectionStrings:{KEY}_ProviderName:
Значение: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Ключ: ConnectionStrings:{KEY}_ProviderName:
Значение: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Ключ: ConnectionStrings:{KEY}_ProviderName:
Значение: System.Data.SqlClient

Переменные среды, заданные в launchSettings.json

Переменные среды, заданные в launchSettings.json, переопределяют переменные, заданные в системной среде.

Параметры Службы приложений Azure

В службе приложение Azure выберите новый параметр приложения на странице Параметры> Configuration. Параметры приложения Службы приложений Azure:

  • Шифруются, когда они неактивны, и передаются по зашифрованному каналу.
  • Предоставляются как переменные среды.

Поставщик конфигурации командной строки

Используя конфигурацию по умолчанию, CommandLineConfigurationProvider конфигурация загружается из пар "ключ-значение" командной строки после следующих источников конфигурации:

  • Файлы appsettings.json и appsettings.Environment.json.
  • Секреты приложения (диспетчер секретов) в среде Development.
  • среды.

По умолчанию значения конфигурации, заданные для значений конфигурации переопределения в командной строке, задаются для всех остальных поставщиков конфигурации.

С помощью Visual Studio 2019 и более поздних версий можно указать аргументы командной строки с помощью диалогового окна "Профили запуска".

Launch Profiles dialog showing command-line arguments

Аргументы командной строки

Следующая команда задает ключи и значения с помощью =:

dotnet run SecretKey="Secret key from command line"

Следующая команда задает ключи и значения с помощью /:

dotnet run /SecretKey "Secret key set from forward slash"

Следующая команда задает ключи и значения с помощью --:

dotnet run --SecretKey "Secret key set from double hyphen"

Значение ключа:

  • Должно соответствовать =, или ключ должен иметь префикс -- или /, когда значение следует за пробелом.
  • Является обязательным, если используется параметр =. Например, SomeKey=.

В рамках одной и той же команды не смешивайте пары "ключ-значение" аргумента командной строки, которые используют = с парами "ключ-значение" с пробелом.

Поставщик конфигурации ключа для каждого файла

KeyPerFileConfigurationProvider использует файлы каталога как пары "ключ — значение" конфигурации. Ключ является именем файла. Значением является содержимое файла. Поставщик конфигурации ключа для каждого файла используется в сценариях размещения Docker.

Чтобы активировать конфигурацию ключа для каждого файла, вызовите метод расширения AddKeyPerFile в экземпляре ConfigurationBuilder. Значение параметра directoryPath должно быть абсолютным путем к файлам.

Перегрузки позволяют указать следующее.

  • Action<KeyPerFileConfigurationSource> — делегат, который настраивает источник.
  • Обязательно ли указывать каталог и путь к каталогу.

Двойное подчеркивание (__) используется в качестве разделителя ключа конфигурации в именах файлов. Например, в имени файла Logging__LogLevel__System создается ключ конфигурации Logging:LogLevel:System.

Чтобы указать конфигурацию приложения, при сборке веб-узла вызовите ConfigureAppConfiguration.

.ConfigureAppConfiguration((_, configuration) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");

    configuration.AddKeyPerFile(directoryPath: path, optional: true);
})

Поставщик конфигурации памяти

MemoryConfigurationProvider использует коллекцию памяти в качестве пар "ключ — значение" конфигурации.

Следующий код добавляет коллекцию памяти в систему конфигурации:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.AddInMemoryCollection(
    new Dictionary<string, string?>
    {
        ["SecretKey"] = "Dictionary MyKey Value",
        ["TransientFaultHandlingOptions:Enabled"] = bool.TrueString,
        ["TransientFaultHandlingOptions:AutoRetryDelay"] = "00:00:07",
        ["Logging:LogLevel:Default"] = "Warning"
    });

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

В приведенном выше коде MemoryConfigurationBuilderExtensions.AddInMemoryCollection(IConfigurationBuilder, IEnumerable<KeyValuePair<String,String>>) добавляет поставщика памяти после поставщиков конфигурации по умолчанию. Пример упорядочивания поставщиков конфигурации см. в разделе Поставщик конфигурации XML.

См. также