Поделиться через


Конфигурация в ASP.NET Core

Note

Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.

Warning

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.

Конфигурация приложения в ASP.NET Core выполняется с помощью одного или нескольких поставщиков конфигурации. Поставщики конфигурации получают данные конфигурации в парах "ключ-значение" из различных источников:

  • файлы настроек, такие как appsettings.json;
  • Переменные среды, включая конфигурацию приложения Azure
  • Azure Key Vault
  • Аргументы командной строки
  • пользовательские поставщики, установленные или созданные;
  • .NET объекты в памяти

В этой статье приведены сведения о конфигурации в ASP.NET Core. Сведения об использовании конфигурации в приложениях non-ASP.NET Core см. в разделе .NET Configuration.

Дополнительные Blazor рекомендации по настройке, которые дополняют или замещают текущие, см. в разделе настройки ASP.NET CoreBlazor.

Эта статья в основном относится к конфигурации приложения. Здесь упоминаются другие типы конфигурации, такие как файлы параметров запуска и web.config файл, но их основная документация находится в другом месте:

Дополнительные сведения о переносе конфигурации приложения из более ранних версий ASP.NET см. в разделе "Миграция конфигурации в ASP.NET Core".

Warning

В этой статье показано, как использовать строки подключения. При использовании локальной базы данных для разработки и тестирования проверка подлинности пользователя базы данных через строку подключения не требуется. В рабочих средах строки подключения иногда включают пароль для проверки подлинности доступа к базе данных или операций базы данных. Учетные данные владельца ресурса (ROPC) в строке подключения представляют собой риск безопасности в производственных приложениях. Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения о проверке подлинности для приложений, развернутых в тестовых или рабочих средах, см. в ASP.NET разделах по безопасности Core.

Примеры в этой статье используют основные конструкторы, доступные в C# 12 (.NET 8) или более поздней версии. Дополнительные сведения см. в разделах "Объявление первичных конструкторов для классов и структур" (учебник по документации по C#) и "Первичные конструкторы" (руководство по C#).

Чтение значений конфигурации

Конфигурация обычно осуществляется путем разрешения IConfiguration сервиса (Microsoft.Extensions.Configuration пространства имен) и использования ключа из пары "ключ-значение" конфигурации для получения значения конфигурации.

В следующем Razor коде компонента показано, как значение конфигурации, технический контактный адрес электронной почты, получен из конфигурации ключом TechnicalContactEmail.

@inject IConfiguration Config

Technical Contact: @Config["TechnicalContactEmail"]

Конфигурация приложения и узла

Приложения ASP.NET Core настраивают и запускают хост. Хост отвечает за запуск приложения и управление временем его существования. Пары "Ключ-значение" конфигурации узла включаются в конфигурацию приложения. Хотя вы можете выполнить некоторую конфигурацию приложения с помощью поставщиков конфигурации узла, мы рекомендуем выполнять только ту, которая необходима для узла.

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

Источники конфигурации приложений по умолчанию

Веб-приложения ASP.NET Core вызывают WebApplication.CreateBuilder, чтобы инициализировать новый экземпляр класса WebApplicationBuilder с предварительно настроенными значениями по умолчанию.

var builder = WebApplication.CreateBuilder(args);

Дополнительные сведения см. в статье Обобщенный хост .NET в ASP.NET Core.

Приложения, созданные на основе вызова Host.CreateDefaultBuilder шаблона проекта веб-приложения ASP.NET Core для инициализации нового экземпляра HostBuilder класса с предварительно настроенными значениями по умолчанию:

Host.CreateDefaultBuilder(args)

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

  1. Аргументы командной строки с помощью поставщика конфигурации командной строки.
  2. Переменные среды не префиксированы или ASPNETCORE_ не DOTNET_ поставщиком конфигурации переменных среды.
  3. Секреты пользователей при запуске приложения в Development среде с помощью поставщика конфигурации файлов.
  4. Конфигурация файла настроек среды приложения с использованием appsettings.{ENVIRONMENT}.json, где заполнителем {ENVIRONMENT} является среда приложения, с помощью поставщика конфигурации JSON. Например, appsettings.Production.json используется в рабочей среде и appsettings.Development.json используется во время разработки.
  5. Общая конфигурация файла параметров приложения с помощью appsettings.jsonпоставщика конфигурации JSON.
  6. Альтернативная конфигурация хоста.

Note

Мы не рекомендуем вызывать CreateBuilder несколько раз исключительно для получения значений конфигурации во время выполнения. Рекомендуется использовать ConfigurationManager (например, builder.Configuration, WebApplicationBuilder.Configuration) или использовать ConfigurationBuilder из соответствующего источника конфигурации.

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

Если значение конфигурации задано в конфигурации узла и приложения, используется конфигурация приложения.

Источники конфигурации узла по умолчанию

Источники конфигурации узла по умолчанию от самого высокого до низкого приоритета при применении к конфигурации веб-приложения (WebApplicationBuilder):

  1. Аргументы командной строки с помощью поставщика конфигурации командной строки.
  2. DOTNET_-префиксированные переменные среды с использованием поставщика конфигурации переменных среды.
  3. ASPNETCORE_-префиксированные переменные среды с использованием поставщика конфигурации переменных среды.

Источники конфигурации узла по умолчанию от самого высокого до низкого приоритета применяются к универсальному узлу или веб-узлу:

  1. ASPNETCORE_-префиксированные переменные среды с использованием поставщика конфигурации переменных среды.
  2. Аргументы командной строки с помощью поставщика конфигурации командной строки.
  3. DOTNET_-префиксированные переменные среды с использованием поставщика конфигурации переменных среды.

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

  • Типовой хост: рекомендуется для приложений ASP.NET Core, предназначенных для .NET 6 или более поздней версии, которые принимают минимальную модель размещения.
  • Веб-хостинг: требуется для приложений ASP.NET Core, которые нацелены на релизы до .NET 6 и поддерживается платформой только для обратной совместимости в .NET 6 или более поздних версиях.

Источники конфигурации узла по умолчанию от самого высокого до низкого приоритета для веб-узла:

Переменные хоста

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

Другие параметры узла считываются из конфигурации приложения вместо конфигурации узла.

URLS — это один из многих общих параметров узла, которые не инициируются конфигурацией узла. URLS считывается позже из конфигурации приложения. Конфигурация хоста — это резервная конфигурация для приложения, поэтому для установки URLS можно использовать конфигурацию хоста, но значение переопределяется любым источником конфигурации, который задает URLS в конфигурации приложения, например, файлы параметров приложения (appsettings.{ENVIRONMENT}.json, где {ENVIRONMENT} — это заполнитель имени среды, или appsettings.json).

Дополнительные сведения см. в "Изменение корневого каталога содержимого, имени приложения и среды" и "Изменение корневого каталога содержимого, имени приложения и среды с использованием переменных среды или командной строки".

Безопасность и секреты пользователей

Рекомендации по данным конфигурации:

  • Никогда не храните пароли или другие конфиденциальные данные в коде поставщика конфигурации или в файлах конфигурации обычного текста. Хранить секреты во время разработки можно с помощью диспетчера секретов.
  • Не используйте секреты рабочей среды в средах разработки и тестирования.
  • Указывайте секреты вне проекта, чтобы их нельзя было случайно зафиксировать в репозитории с исходным кодом.
  • Рабочие приложения должны использовать самый безопасный поток проверки подлинности. Дополнительные сведения см. в разделе "Безопасные потоки проверки подлинности".

Источник конфигурации файла секретов пользователя из источников конфигурации по умолчанию регистрируется после источников конфигурации JSON для файлов параметров приложения. Таким образом, ключи секретов пользователя имеют приоритет над ключами в appsettings.json и appsettings.{ENVIRONMENT}.json.

Дополнительные сведения о хранении паролей или других конфиденциальных данных:

Настройка доступа с использованием внедрения зависимостей (DI)

Конфигурацию можно внедрить в службы с помощью внедрения зависимостей (DI), через резолвинг IConfiguration службы. В следующем примере значение конфигурации, сохраненное для ключа конфигурации, представленного заполнителем {KEY}, присваивается value. Если ключ не найден, null присваивается value:

public class CustomService(IConfiguration config)
{
    public void CustomMethod()
    {
        var value = config["{KEY}"];
    }
}

Доступ к конфигурации в Program файле

Следующий код обращается к конфигурации в Program файле с помощью WebApplicationBuilder.Configuration (builder.Configuration):

var defaultConnectionString = 
   builder.Configuration.GetValue<string>("ConnectionStrings:DefaultConnection");

После создания приложения (после строки var app = builder.Build();) используйте WebApplication.Configuration (app.Configuration):

var defaultLogLevel = app.Configuration.GetValue<string>("Logging:LogLevel:Default");

Конфигурация доступа в Startup классе

Этот раздел обычно применяется к приложениям ASP.NET Core до выпуска .NET 6.

В следующем коде отображаются данные конфигурации в методах Startup:

public class Startup
{
    public Startup(IConfiguration config)
    {
        Config = config;
    }

    public IConfiguration Config { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var connectionString = Config["ConnectionStrings.DefaultConnection"];

        ...
    }

    public void Configure(...)
    {
        var defaultLogLevel = Config["Logging:LogLevel:Default"];

        ...
    }
}

Отображение параметров конфигурации при запуске для отладки

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

После сборки приложения в Program файл (после строки var app = builder.Build();) поместите следующий код, включающий директиву компилятора для конфигурации DEBUG:

#if DEBUG
foreach (var c in app.Configuration.AsEnumerable())
{
    Console.WriteLine($"CONFIG: Key: {c.Key} Value: {c.Value}");
}
#endif

В конструкторе класса приложения Startup внедрите IConfiguration, config в следующем примере, чтобы вывести пары ключей и значений конфигурации в консоль. В следующем примере содержится директива компилятора для конфигурации DEBUG:

#if DEBUG
foreach (var c in config.AsEnumerable())
{
    Console.WriteLine($"CONFIG: Key: {c.Key} Value: {c.Value}");
}
#endif

Ключи и значения конфигурации

Ключи конфигурации:

  • Являются нечувствительными к регистру. Например ConnectionString и connectionstring обрабатываются как эквивалентные ключи.
  • Если ключ и значение заданы несколькими поставщиками конфигурации, используется значение из последнего добавленного поставщика. Дополнительные сведения см. в разделе Конфигурация по умолчанию.
  • Иерархические ключи
    • В API конфигурации двоеточие в качестве разделителя (:) поддерживается на всех платформах.
    • В переменных среды разделитель двоеточия не работает на всех платформах. Двойное подчеркивание (__) поддерживается всеми платформами и автоматически преобразуется в двоеточие (:), когда конфигурация читается приложением.
    • В Azure Key Vault иерархические ключи используют двойные дефисы (--) в качестве разделителя. Поставщик конфигурации Azure Key Vault автоматически заменяет двойные дефисы (--) двоеточием (:) при загрузке секретов в конфигурацию приложения.
  • ConfigurationBinder поддерживает привязку массивов к объектам с использованием индексов массива в ключах конфигурации. Привязка массива описана в разделе "Привязка массива ".

Значения конфигурации — это строки. Значение NULL не может храниться в конфигурации или быть привязанным к объектам.

Как организованы иерархические данные конфигурации

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

Note

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

Рассмотрим следующие иерархические данные конфигурации:

  • ConnectionStrings
    • DefaultConnection (Value = 'Data Source=LocalSqlServer\MSSQLDev;')
  • Logging
    • LogLevel
      • Default (Value = 'Information')
      • Microsoft (Value = 'Warning')
      • Microsoft.Hosting.Lifetime (Value = 'Information')
  • AllowedHosts (Value = '*')

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

Ключ (разделитель двоеточия) Ключ (разделитель с двойным подчеркиванием)
ConnectionStrings:DefaultConnection ConnectionStrings__DefaultConnection
Logging:LogLevel:Default Logging__LogLevel__Default
Logging:LogLevel:Microsoft Logging__LogLevel__Microsoft
Logging:LogLevel:Microsoft.Hosting.Lifetime Logging__LogLevel__Microsoft.Hosting.Lifetime
AllowedHosts AllowedHosts

Note

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

Методы GetSection и GetChildren доступны для изолирования разделов и дочерних элементов раздела в данных конфигурации. Эти методы описываются, где GetSectionи GetChildrenExistsрассматриваются.

Если структура элементов содержит массив, индекс массива должен рассматриваться как дополнительное имя элемента в пути. Рассмотрим следующие иерархические данные конфигурации как массив.

MainObject (массив):

  • Первый элемент в массиве
    • Object0
    • Object1
      • SubObject0
      • SubObject1
  • Второй элемент в массиве
    • Object0
    • Object1
      • SubObject0
      • SubObject1

Ключи с разделителями двоеточий:

  • MainObject:0:Object0
  • MainObject:0:Object1:SubObject0
  • MainObject:0:Object1:SubObject1
  • MainObject:1:Object0
  • MainObject:1:Object1:SubObject0
  • MainObject:1:Object1:SubObject1

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

  • MainObject__0__Object0
  • MainObject__0__Object1:SubObject0
  • MainObject__0__Object1:SubObject1
  • MainObject__1__Object0
  • MainObject__1__Object1:SubObject0
  • MainObject__1__Object1:SubObject1

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

Modules значения (массив):

  • Module1
  • Module2
  • Module3

Массив развернут и индексирован последовательно, образуя пары "ключ-значение конфигурации" в следующей таблице.

Key Ценность
Modules:0 Module1
Modules:1 Module2
Modules:2 Module3

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

Modules значения (массив):

  • Module4
  • Module5

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

Key Ценность
Modules:0 Module4
Modules:1 Module5

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

Key Ценность
Modules:0 Module4
Modules:1 Module5
Modules:2 Module3

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

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

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

В следующей таблице показаны поставщики конфигурации, доступные для приложений ASP.NET Core.

Provider Предоставляет конфигурацию из...
Поставщик конфигурации Azure Key Vault Azure Key Vault
Поставщик конфигурации приложений Azure Настройка приложения Azure
Поставщик конфигурации командной строки Параметры командной строки
Поставщик пользовательской конфигурации Пользовательский источник
Поставщик конфигурации переменных среды Переменные среды
Поставщик конфигурации файлов Файлы INI, JSON и XML
Поставщик конфигурации с ключом для каждого файла Файлы каталогов
Поставщик конфигурации памяти Коллекции в памяти
Секреты пользователей Файл в каталоге профиля пользователя

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

Типичная последовательность поставщиков конфигурации.

  1. Общие параметры приложения с помощью appsettings.json.
  2. Настройки приложения окружения с использованием appsettings.{ENVIRONMENT}.json, где плейсхолдер {ENVIRONMENT} представляет собой среду приложения (примеры: Development, Production).
  3. Секреты пользователей.
  4. Переменные среды с помощью провайдера конфигурации переменных среды.
  5. Аргументы командной строки с помощью поставщика конфигурации командной строки.

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

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

Чтобы проверить поставщиков конфигурации приложения, инъектироватьIConfiguration, привести к IConfigurationRoot, и прочитать Providers свойство.

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

Pages/ConfigurationProviders.razor:

@page "/configuration-providers"
@inject IConfiguration Config

<h1>Configuration Providers</h1>

@if (ConfigRoot is not null)
{
    <ul>
        @foreach (var provider in ConfigRoot.Providers)
        {
            <li>@provider</li>
        }
    </ul>
}

@code {
    private IConfigurationRoot? ConfigRoot;

    protected override void OnInitialized()
    {
        ConfigRoot = (IConfigurationRoot)Config;
    }
}

Razor Предыдущий компонент генерирует следующий вывод, где заполнитель {APP NAMESPACE} соответствует пространству имен приложения.

MemoryConfigurationProvider
EnvironmentVariablesConfigurationProvider Prefix: 'ASPNETCORE_'
MemoryConfigurationProvider
EnvironmentVariablesConfigurationProvider Prefix: 'DOTNET_'
JsonConfigurationProvider for 'appsettings.json' (Optional)
JsonConfigurationProvider for 'appsettings.Development.json' (Optional)
JsonConfigurationProvider for '{APP NAMESPACE}.settings.json' (Optional)
JsonConfigurationProvider for '{APP NAMESPACE}.settings.Development.json' (Optional)
EnvironmentVariablesConfigurationProvider
Microsoft.Extensions.Configuration.ChainedConfigurationProvider

В разделе "Источники конфигурации приложений по умолчанию " ранее в этой статье источники конфигурации перечислены от самого высокого до низкого приоритета. ConfigurationProviders Предыдущий компонент отображает источники в том порядке, в котором приложение считывает их. Например, поставщик конфигурации JSON для файла параметров не экологических приложений (appsettings.json) выше в предыдущем списке, так как он добавляется перед поставщиком файла параметров приложения среды разработки (appsettings.Development.json). Поставщики конфигурации выполняются сверху вниз по списку. Для ключа конфигурации, совпадающего в настройках двух приложений, последний параметр, задаваемый поставщиками конфигурации JSON, имеет приоритет, то есть значение из appsettings.Development.json.

Конфигурация файла параметров приложения (appsettings.json, appsettings.{ENVIRONMENT}.json)

Чтение конфигурации, загруженной из файлов параметров приложения с помощью поставщика конфигурации JSON.

Рассмотрим следующий файл appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=LocalSqlServer\\MSSQLDev;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Внедрите экземпляр IConfiguration, чтобы читать значения конфигурации.

AppSettingsConfiguration Razor Следующий компонент считывает строку подключения базы данных по умолчанию и конфигурацию уровня ведения журнала по умолчанию. IConfiguration внедряется в верхней части компонента и используется для чтения значений конфигурации. Разделитель двоеточия (:) используется в ключах конфигурации с строковым типом для поиска соответствующих свойств JSON. Например, структура JSON для объекта строки подключения по умолчанию (DefaultConnection) вложена в объект строк подключения (ConnectionStrings), поэтому запись строки для доступа к строке подключения по умолчанию использует двоеточие для разделения DefaultConnection и ConnectionStrings в порядке, в котором объекты отображаются в файле настроек приложения: ConnectionStrings:DefaultConnection.

Pages/AppSettingsConfiguration.razor:

@page "/app-settings-configuration"
@inject IConfiguration Config

<h1>App Settings Configuration</h1>

<ul>
    <li>Default Connection String: @Config["ConnectionStrings:DefaultConnection"]
    <li>Default Log Level: @Config["Logging:LogLevel:Default"]
</ul>

Тот же подход применяется в модели страницы Pages:

using Microsoft.Extensions.Configuration;

...

public class AppSettingsPageModel(IConfiguration config) : PageModel
{
    public ContentResult OnGet()
    {
        var defaultConnectionString = config["ConnectionStrings:DefaultConnection"];
        var defaultLogLevel = config["Logging:LogLevel:Default"];

        return Content(
            $"Default Connection String: {defaultConnectionString}\n" +
            $"Default Log Level: {defaultLogLevel}");
    }
}

Конфигурация загрузки экземпляров JsonConfigurationProvider по умолчанию происходит в следующем порядке:

  1. appsettings.json
  2. appsettings.{ENVIRONMENT}.json, где заполнитель {ENVIRONMENT} — это среда приложения (примеры: appsettings.Production.json, appsettings.Development.json). Версия файла среды загружается на основе IHostingEnvironment.EnvironmentName.

Значения appsettings.{ENVIRONMENT}.json переопределяют ключи в файле appsettings.json.

По умолчанию:

  • В среде разработки appsettings.Development.json конфигурация перезаписывает значения, найденные в appsettings.json.
  • В рабочей среде appsettings.Production.json конфигурация перезаписывает значения, найденные в appsettings.json.

В предыдущем примере считываются только строки и не поддерживаются значения по умолчанию. Если необходимо гарантировать значение конфигурации с использованием значения по умолчанию, см. раздел «Извлечение одного значения из конфигурации с преобразованием типов» (GetValue).

Используя источники конфигурации приложений по умолчанию, файлы appsettings.json и appsettings.{ENVIRONMENT}.json включены с reloadOnChange заданным значением true. Это означает, что изменения в файлах appsettings.json или appsettings.{ENVIRONMENT}.json, внесенные после запуска приложения, вступают в силу сразу после сохранения файла.

Комментарии в файлах appsettings.json и appsettings.{ENVIRONMENT}.json поддерживаются в стиле JavaScript или C#. Некоторые интегрированные среды разработки (IDEs) отображают ошибки при редактировании JSON-файла, содержащего примечания, так как официальная спецификация JSON (RFC 7159) не делает никаких ограничений для комментариев в JSON-файлах. В общем, вы можете игнорировать ошибки в комментариях и предупреждения, но также можете обычно отключать предупреждения или ошибки посредством настройки в интегрированной среде разработки. Например, в Visual Studio Code добавьте следующее в файл settings.json, чтобы отключить ошибки.

"files.associations": {
  "appsettings*.json": "jsonc"
}

Предыдущий параметр указывает на VS Code, что файлы параметров приложения, включая экологические файлы, связаны с форматом файла JSONC (JSON with Comments), который поддерживает комментарии.

Чтобы определить, как отключить уведомления об ошибках или предупреждениях о комментариях в JSON-файлах, ознакомьтесь с документацией и каналами поддержки других интегрированных сред разработки.

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

Поставщик конфигурации переменных среды по умолчанию загружает конфигурацию из переменных среды, которые не имеют префикса или . Дополнительные сведения о ASPNETCORE_ и DOTNET_ переменных среды см. в разделе источников конфигурации узла по умолчанию и DOTNET_ переменных среды (документация по .NET Core).

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

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

Инструкции по настройке переменных среды в командной оболочке Windows или в кроссплатформенной командной оболочке PowerShell см. в следующих ресурсах:

Настраиваемый префикс для переменных среды

Вы можете добавить поставщика конфигурации для переменных среды с пользовательским префиксом. В файле Program вызовите AddEnvironmentVariables с строкой, чтобы указать префикс после вызова WebApplication.CreateBuilder. Поставщик добавляется после поставщиков конфигурации по умолчанию, поэтому добавленный поставщик имеет более высокий приоритет, включая переменные среды с тем же именем без префикса.

В следующем примере переменные среды добавляются с CustomPrefix_ префиксом:

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

Вы можете добавить поставщика конфигурации для переменных среды с пользовательским префиксом. В файле Program вызовите AddEnvironmentVariables со строкой, чтобы указать префикс на IConfigurationBuilder от ConfigureAppConfiguration. Поставщик добавляется после поставщиков конфигурации по умолчанию, поэтому добавленный поставщик имеет более высокий приоритет, включая переменные среды с тем же именем без префикса.

В следующем примере переменные среды добавляются с CustomPrefix_ префиксом:

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

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

Параметры запуска заменяют параметры переменной среды

Переменные среды, заданные в launchSettings.json, переопределяют переменные, заданные в системной среде. Например, веб-шаблоны ASP.NET Core создают launchSettings.json файл, который задает конфигурацию конечной точки следующим образом:

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

При настройке applicationUrl устанавливается переменная среды ASPNETCORE_URLS и переопределяются значения, заданные в среде.

Экранирование переменных среды в Linux

В Linux значения переменных среды URL-адресов нужно экранировать, чтобы systemd мог их проанализировать. В следующем примере средство systemd-escape Linux используется для получения http:--localhost:5001 от http://localhost:5001:

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

Параметры приложения Службы приложений Azure (переменные среды)

Рекомендации по настройкам приложения Службы приложений Azure (переменные окружения) см. в следующих ресурсах:

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

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

Command-line

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

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

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

Следующая dotnet run команда задает ключи и значения с помощью знаков равенства (=):

dotnet run ConnectionStrings:DefaultConnection="Data Source=LocalSqlServer\\MSSQLDev;" Logging:LogLevel:Default=Information

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

dotnet run /ConnectionStrings:DefaultConnection "Data Source=LocalSqlServer\\MSSQLDev;" /Logging:LogLevel:Default Information

Следующая команда задает ключи и значения с помощью двойных дефисов (--):

dotnet run --ConnectionStrings:DefaultConnection "Data Source=LocalSqlServer\\MSSQLDev;" --Logging:LogLevel:Default Information

Правила использования аргументов:

  • Значение ключа должно следовать за знаком равенства (=), или ключ должен иметь префикс из двойного дефиса (--) или косой черты (/), если значение следует после пробела.
  • Не назначая значение после знака равенства (=) приводит к назначению пустой строки для параметра конфигурации. Например, указание ConnectionStrings:DefaultConnection= допустимо и приводит к назначению пустой строки строке подключения по умолчанию.
  • В той же команде не смешивайте пары аргумента key-value, разделенные знаком равенства (=) с парами "ключ-значение", разделенными пробелом.

Сопоставления коммутаторов

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

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

Правила ключей из словаря сопоставления переключений:

  • Переключатели должны начинаться с одного дефиса (-) или двойного дефиса (--).
  • Словарь сопоставлений переключений не должен содержать повторяющиеся ключи.

В следующем примере словарь сопоставления коммутаторов передаетсяswitchMappingsAddCommandLine в файл приложенияProgram:

var switchMappings = 
    new Dictionary<string, string>(){ { "-k1", "key1" }, { "-k2", "key2" } };

builder.Configuration.AddCommandLine(args, switchMappings);
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
.ConfigureAppConfiguration(config =>
{ 
    var switchMappings =
        new Dictionary<string, string>() { { "-k1", "key1" }, { "-k2", "key2" } };

    config.AddCommandLine(args, switchMappings);
});

dotnet run Следующие команды демонстрируют замену ключей (value1 в key1 и value2 в key2):

  • dotnet run -k1 value1 -k2 value2
  • dotnet run --k1=value1 --k2=value2
  • dotnet run --k1 value1 --k2 value2
  • dotnet run /k1=value1 /k2=value2
  • dotnet run /k1 value1 /k2 value2

Для приложений, использующих сопоставления переключений, в вызове CreateDefaultBuilder аргументы передаваться не должны. Вызов метода CreateDefaultBuilderAddCommandLine не включает сопоставленные переключатели, и нет возможности передать словарь отображения переключателей в CreateDefaultBuilder. Чтобы решить эту проблему, нужно не передавать аргументы команде CreateDefaultBuilder, а позволить методу AddCommandLine из ConfigurationBuilder обрабатывать как аргументы, так и словарь сопоставления переключателей.

Для приложений, использующих сопоставления переключений, в вызове CreateDefaultBuilder аргументы передаваться не должны. Вызов CreateDefaultBuilder метода AddCommandLine не включает сопоставленные переключатели, и нет возможности передать словарь сопоставления переключателей в CreateDefaultBuilder. Чтобы решить эту проблему, нужно не передавать аргументы команде CreateDefaultBuilder, а позволить методу AddCommandLine, принадлежащему методу IConfigurationBuilder, обрабатывать как аргументы, так и словарь сопоставления параметров.

Настройка среды и аргументов командной строки с помощью Visual Studio

Аргументы среды и командной строки можно задать в Visual Studio в диалоговом окне профилей запуска:

  • В Обозревателе решений щелкните проект правой кнопкой мыши и выберите Свойства.
  • Откройте вкладку Отладка > Общие и выберите пункт Открыть пользовательский интерфейс профилей запуска отладки.

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

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

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

IniConfigurationProvider загружает конфигурацию из пар "ключ-значение" INI файла. В следующем примере показано, как использовать поставщика. Перегрузки могут указывать, является ли файл необязательным и если конфигурация перезагружается при изменении файла.

IniConfig.ini:

[ConnectionStrings]
DefaultConnection="Data Source=LocalSqlServer\\MSSQLDev;"

[Logging:LogLevel]
Default=Debug
Microsoft=Debug

IniConfig.Production.ini:

[ConnectionStrings]
DefaultConnection="Data Source=LocalSqlServer\\MSSQLProd;"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

Загрузите конфигурацию путем вызова AddIniFile. В следующем примере создается источник конфигурации для каждого из предыдущих файлов. Конфигурация внешнего файла будет перезагружена, если файл изменен (reloadOnChange параметр, по умолчанию: false). Версия файла среды указывает, что файл является необязательным (optional параметр, значение по умолчанию: false). Если вы хотите указать перезагрузку файла при изменении (reloadOnChange: true), необходимо также указать, является ли файл необязательным (optional).

builder.Configuration
    .AddIniFile("IniConfig.ini", optional: false, reloadOnChange: true);
    .AddIniFile($"IniConfig.{builder.Environment.EnvironmentName}.ini", optional: true);
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
.ConfigureAppConfiguration(config =>
{ 
    config
        .AddIniFile("IniConfig.ini", optional:false, reloadOnChange: true)
        .AddIniFile("IniConfig.Production.ini", optional: true);
});

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

JsonConfigurationProvider загружает конфигурацию из JSON-файла, представляющего собой пары "ключ-значение". В следующем примере показано, как использовать поставщика. Перегрузки могут указывать, является ли файл необязательным и если конфигурация перезагружается при изменении файла.

Вызовите AddJsonFile, указав путь к файлу (или имя файла, если файл находится в корне приложения). В следующем случае файл необязателен (optional параметр, по умолчанию: false) и указывает, что конфигурация перезагрузится, если файл изменен (reloadOnChange параметр, по умолчанию: false). Если вы хотите указать перезагрузку файла при изменении (reloadOnChange: true), необходимо также указать, является ли файл необязательным (optional).

builder.Configuration.AddJsonFile("config.json", optional: true, reloadOnChange: true);
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
.ConfigureAppConfiguration(config =>
{ 
    config.AddJsonFile("config.json", optional: true, reloadOnChange: true);
});

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

Загружает XmlConfigurationProvider конфигурацию из XML-файла, содержащего пары "ключ-значение". В следующем примере показано, как использовать поставщика. Перегрузки могут указывать, является ли файл необязательным и если конфигурация перезагружается при изменении файла.

XmlFile.xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <ConnectionStrings>
    <DefaultConnection>Data Source=LocalSqlServer\\MSSQLDev;</DefaultConnectionString>
  </ConnectionStrings>
  <Logging>
    <LogLevel>
      <Default>Debug</Default>
      <Microsoft>Debug</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

XmlFile.Production.xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <ConnectionStrings>
    <DefaultConnectionString>Data Source=LocalSqlServer\\MSSQLProd;</DefaultConnectionString>
  </ConnectionStrings>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

Загрузите конфигурацию путем вызова AddXmlFile. В следующем примере создается источник конфигурации для каждого из предыдущих файлов. Конфигурация внешнего файла будет перезагружена, если файл изменен (reloadOnChange параметр, по умолчанию: false). Версия файла среды указывает, что файл является необязательным (optional параметр, значение по умолчанию: false). Если вы хотите указать перезагрузку файла при изменении (reloadOnChange: true), необходимо также указать, является ли файл необязательным (optional).

builder.Configuration
    .AddXmlFile("XmlFile.xml", optional: false, reloadOnChange: true);
    .AddXmlFile($"XmlFile.{builder.Environment.EnvironmentName}.xml", optional: true);
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
.ConfigureAppConfiguration(config =>
{ 
    config
        .AddXmlFile("XmlFile.xml", optional:false, reloadOnChange: true)
        .AddXmlFile("XmlFile.Production.xml", optional: true);
});

Повторяющиеся элементы, использующие то же имя элемента, работают, если атрибут name используется для различения элементов.

<?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>
var value_00 = Config["section:section0:key:key0"];
var value_01 = Config["section:section0:key:key1"];
var value_10 = Config["section:section1:key:key0"];
var value_11 = Config["section:section1:key:key1"];

Поддерживаются атрибуты, которые предоставляют значения:

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

Предыдущая конфигурация загружает следующие ключи с value:

  • key:attribute
  • section:key:attribute

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

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

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

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

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

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

var path = Path.Combine(Directory.GetCurrentDirectory(), "path/to/files");
builder.Configuration.AddKeyPerFile(directoryPath: path, optional: true);
.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

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

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

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

var configSettings = new Dictionary<string, string>
{
    { "ConnectionStrings:DefaultConnection", "Data Source=LocalSqlServer\\MSSQLDev;" },
    { "Logging:LogLevel:Default", "Information" }
};

builder.Configuration.AddInMemoryCollection(configSettings);
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
    .ConfigureAppConfiguration(config =>
    { 
        var configSettings = new Dictionary<string, string>
        {
            { "ConnectionStrings:DefaultConnection", "Data Source=LocalSqlServer\\MSSQLDev;" },
            { "Logging:LogLevel:Default", "Information" }
        };

        config.AddInMemoryCollection(configSettings);
    });

Конфигурация конечной точки Kestrel

KestrelКонфигурация конкретной конечной точки переопределяет все конфигурации межсерверных конечных точек. Конфигурации межсерверных конечных точек включают:

Рассмотрим следующий Kestrel раздел конфигурации в appsettings.json файле:

"Kestrel": {
  "Endpoints": {
    "Https": {
      "Url": "https://localhost:9999"
    }
  }
},

Приложение запускается в командной строке с dotnet run следующей конфигурацией межсерверного конечного узла:

dotnet run --urls="https://localhost:7777"

Kestrel привязывается к конечной точке, настроенной специально для Kestrel в файле appsettings.json, а не к конфигурации межсерверной конечной точки, переданной команде https://localhost:9999 (dotnet runhttps://localhost:7777).

Однако рассмотрим конкретную конечную точку Kestrel, настроенную в качестве переменной среды:

  • Ключ: Kestrel__Endpoints__Https__Url.
  • Значение: https://localhost:8888

В предыдущей переменной среды "Https" — это имя конкретной конечной Kestrelточки. Предыдущая конфигурация параметров приложения также определяет определенную конечную точку Kestrelс именем Https. Для поставщиков конфигурации узла по умолчанию переменные среды, считываемые поставщиком конфигурации переменных среды , считываются после appsettings.{ENVIRONMENT}.json. Таким образом, предыдущая переменная среды (Kestrel__Endpoints__Https__Url) используется для конечной Https точки.

Извлечение одного значения из конфигурации с преобразованием типов (GetValue)

ConfigurationBinder.GetValue извлекает одно значение из конфигурации с указанным ключом и преобразует его в указанный тип:

var number = Config.GetValue<int>("NumberKey", 99);

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

  • Config внедрён в IConfiguration.
  • Если NumberKey в конфигурации не найдено, используется значение 99 по умолчанию.

Работа с разделами, получение дочерних разделов и проверка существования раздела

В следующих примерах рассмотрим файл subsection.json.

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

Поставщик конфигурации добавляется для subsection.json посредством вызова AddJsonFile.

GetSection

IConfiguration.GetSection возвращает подраздел конфигурации с указанным ключом подраздела.

Следующий код возвращает значения для section1, где Config является внедрённым IConfiguration:

var subsection = Config.GetSection("section1");
var value1 = subsection["key0"];
var value2 = subsection["key1"];

Следующий код возвращает значения для section2:subsection0, где Config является внедрённым IConfiguration:

var subsection = Config.GetSection("section2:subsection0");
var value1 = subsection["key0"];
var value2 = subsection["key1"];

GetSection никогда не возвращает null. Если соответствующий раздел не найден, возвращается пустой параметр IConfigurationSection.

Когда GetSection возвращает соответствующий раздел, Value не заполняется. Если раздел существует, возвращаются Key и Path.

GetChildren и Exists.

Следующие фрагменты кода:

var section = Config.GetSection("section2");

if (!section.Exists())
{
    throw new Exception("section2 doesn't exist!");
}

var children = section.GetChildren();

foreach (var subSection in children)
{
    int i = 0;
    var key1 = subSection.Key + ":key" + i++.ToString();
    var key2 = subSection.Key + ":key" + i.ToString();
    Console.WriteLine($"{key1} value: {section[key1]}");
    Console.WriteLine($"{key2} value: {section[key2]}");
}

Выходные данные:

subsection0:key0 value: value200
subsection0:key1 value: value201
subsection1:key0 value: value210
subsection1:key1 value: value211

Свяжите массив

ConfigurationBinder.Bind поддерживает привязку массивов к объектам с использованием индексов массива в ключах конфигурации. Любой формат массива, который предоставляет сегмент числового ключа способен привязать массив к массиву класса POCO.

array.json:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

Поставщик конфигурации добавляется для array.json посредством вызова AddJsonFile.

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

ArrayExample.cs:

public class ArrayExample
{
    public string[]? Entries { get; set; } 
}
var array = Config.GetSection("array").Get<ArrayExample>();

if (array is null)
{
    throw new ArgumentNullException(nameof(array));
}

for (int j = 0; j < array.Entries?.Length; j++)
{
    Console.WriteLine($"Index: {j} Value: {array.Entries[j]}");
}

Выходные данные:

Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value40
Index: 4 Value: value50

В предыдущих результатах индекс 3 имеет значение value40, соответствующее "4": "value40", в array.json. Индексы привязанного массива непрерывны и не привязаны к индексу ключа конфигурации. Конфигурационный модуль не способен привязывать значения null или создавать элементы null в связанных объектах.

Отсутствующий элемент конфигурации индекса 3 можно предоставить перед привязкой к ArrayExample экземпляру любым поставщиком конфигурации, который считывает пару "Ключ-значение индекса 3". В следующем примере предполагается, что значения, предоставленные array.json в предыдущем примере, предоставляются коллекцией в памяти. В примере показано, как загрузить значение Индекса 3 из поставщика конфигурации JSON до привязки коллекции.

value3.json:

{
  "array:entries:3": "value30"
}
var configSettings = new Dictionary<string, string>
{
    { "array:entries:0", "value00" },
    { "array:entries:1", "value10" },
    { "array:entries:2", "value20" },
    { "array:entries:4", "value40" },
    { "array:entries:5", "value50" }
};

builder.Configuration.AddInMemoryCollection(configSettings);
builder.Configuration.AddJsonFile("value3.json", optional: false, 
    reloadOnChange: false);
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
    .ConfigureAppConfiguration(config =>
    { 
        var configSettings = new Dictionary<string, string>
        {
            { "array:entries:0", "value00" },
            { "array:entries:1", "value10" },
            { "array:entries:2", "value20" },
            { "array:entries:4", "value40" },
            { "array:entries:5", "value50" }
        };

        config.AddInMemoryCollection(configSettings);
        config.AddJsonFile("value3.json", optional: false, reloadOnChange: false);
    });

Предыдущий код приводит к следующему ограничивающему массиву:

Index: 0 Value: value00
Index: 1 Value: value10
Index: 2 Value: value20
Index: 3 Value: value30
Index: 4 Value: value40
Index: 5 Value: value50

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

Пример приложения демонстрирует, как создать базового поставщика конфигурации, который считывает пары "ключ — значение" конфигурации из базы данных, используя Entity Framework (EF).

Поставщик имеет следующие характеристики.

  • База данных в памяти EF используется для демонстрационных целей. Чтобы использовать базу данных, для которой требуется строка подключения, реализуйте дополнительный ConfigurationBuilder, чтобы предоставить строку подключения от другого поставщика конфигурации.
  • Поставщик считывает таблицу базы данных для конфигурации при запуске. Поставщик не запрашивает базу данных для каждого ключа.
  • Функция перезагрузки на изменение не реализована, поэтому обновление базы данных после запуска приложения не влияет на конфигурацию приложения.

Определите сущность EFConfigurationValue для хранения значений конфигурации в базе данных.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = string.Empty;
    public string Value { get; set; } = string.Empty;
}

Добавьте EFConfigurationContext, чтобы хранить и получать доступ к настроенным значениям.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(
        DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
// using Microsoft.EntityFrameworkCore;

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values { get; set; }
}

Создайте класс, реализующий IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

Note

В примере требуются следующие using инструкции:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => 
        _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => 
        new EFConfigurationProvider(_optionsAction);
}

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

EFConfigurationProvider/EFConfigurationProvider.cs:

using Microsoft.EntityFrameworkCore;

public class EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction) : ConfigurationProvider
{
    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        optionsAction(builder);

        using var dbContext = new EFConfigurationContext(builder.Options);

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Database.EnsureCreated();

        Data = !dbContext.Values.Any()
            ? CreateAndSaveDefaultValues(dbContext)
            : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
    }

    private static Dictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "quote1", "I aim to misbehave." },
                { "quote2", "I swallowed a bug." },
                { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}
// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues = 
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "quote1", "I aim to misbehave." },
                { "quote2", "I swallowed a bug." },
                { "quote3", "You can't stop the signal, Mal." }
            };

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue 
                {
                    Id = kvp.Key,
                    Value = kvp.Value
                })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Метод расширения AddEFConfiguration позволяет добавить источник конфигурации к ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

Note

В примере требуются следующие using инструкции:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
        this IConfigurationBuilder builder,
        Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

В следующем коде показано, как использовать пользовательский EFConfigurationProvider в файле Program приложения:

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddEFConfiguration(
                options => options.UseInMemoryDatabase("InMemoryDb"));
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Пример доступа к конфигурации с использованием удобных методов запуска см. в разделе Запуск приложения. Удобные методы.

Добавление конфигурации из внешней сборки

Реализация IHostingStartup позволяет при запуске добавлять в приложение улучшения из внешней сборки вне приложения класса Startup. Дополнительные сведения см. в разделе Использование начальных сборок размещения в ASP.NET Core.

Генератор для привязки конфигурации к источнику

Генератор кода привязки конфигурации предоставляет дружественную к AOT и обрезке конфигурацию. Дополнительные сведения см. в разделе генератор исходного кода привязки конфигурации.

Дополнительные ресурсы