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

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

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

Примечание.

Сведения о настройке самой среды выполнения .NET см . в параметрах конфигурации среды выполнения .NET.

Основные понятия и абстракции

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

The `IConfiguration` interface is a single representation of all the configuration sources.

Конфигурация консольных приложений

Консольные приложения .NET, созданные с помощью нового шаблона команд dotnet или Visual Studio по умолчанию , не предоставляют возможности конфигурации. Чтобы добавить конфигурацию в новое консольное приложение .NET, добавьте ссылку на пакет в Microsoft.Extensions.Configuration. Этот пакет является основой для настройки в приложениях .NET. Он предоставляет ConfigurationBuilder и связанные типы.

using Microsoft.Extensions.Configuration;

var configuration = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>()
    {
        ["SomeKey"] = "SomeValue"
    })
    .Build();

Console.WriteLine(configuration["SomeKey"]);

// Outputs:
//   SomeValue

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

  • Создает новый экземпляр ConfigurationBuilder.
  • Добавляет в построитель конфигураций коллекцию пар "ключ-значение" в памяти.
  • Build() Вызывает метод для создания экземпляраIConfiguration.
  • Записывает значение SomeKey ключа в консоль.

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

Альтернативный подход к размещению

Как правило, приложения будут выполнять больше, чем просто конфигурацию чтения. Скорее всего, они будут использовать внедрение зависимостей, ведение журнала и другие службы. Подход универсального узла .NET рекомендуется для приложений, использующих эти службы. Вместо этого рекомендуется добавить ссылку на пакет в Microsoft.Extensions.Hosting. Измените файл Program.cs в соответствии с приведенным ниже кодом:

using Microsoft.Extensions.Hosting;

using IHost host = Host.CreateApplicationBuilder(args).Build();

// Application code should start here.

await host.RunAsync();

Метод Host.CreateApplicationBuilder(String[]) предоставляет конфигурацию по умолчанию для приложения в следующем порядке: от самого высокого до низкого приоритета:

  1. Аргументы командной строки, использующие поставщик конфигурации командной строки.
  2. Переменные среды, использующие поставщик конфигурации переменных среды.
  3. Секреты приложения, когда приложение выполняется в среде Development.
  4. Файл appsettings.json, использующий поставщик конфигурации JSON.
  5. Файл appsettings.Environment.json, использующий поставщик конфигурации JSON. Например, appsettings.Production.json и appsettings.Development.json.
  6. ChainedConfigurationProvider: добавляет существующий IConfiguration в качестве источника.

Добавление поставщика конфигурации переопределяет предыдущие значения конфигурации. Например, поставщик конфигурации командной строки переопределяет все значения от других поставщиков, так как он добавлен последним. Если SomeKey задано как в appsettings.json, так и в среде используется значение среды, так как оно было добавлено после appsettings.json.

Привязка

Одним из ключевых преимуществ абстракций для конфигурации .NET является возможность привязки значений конфигурации к экземплярам объектов .NET. Например, поставщика конфигурации JSON можно использовать для сопоставления файлов appsettings.json с объектами .NET и использовать с помощью внедрения зависимостей. Это позволяет применять шаблоны параметров, которые используют классы для обеспечения строго типизированного доступа к группам связанных параметров. Конфигурация .NET предоставляет различные абстракции. Рассмотрим следующие интерфейсы:

  • IConfiguration — предоставляет набор свойств конфигурации приложения в виде "ключ — значение".
  • IConfigurationRoot: представляет корень IConfiguration иерархии.
  • IConfigurationSection — представляет раздел значений конфигурации приложения.

Эти конфигурации не зависят от базового поставщика конфигурации (IConfigurationProvider). То есть вы можете использовать экземпляр IConfiguration для доступа к любому значению конфигурации от нескольких поставщиков.

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

  • Прямая десериализация (с помощью встроенных преобразователей) для примитивных типов.
  • Сложный TypeConverter тип, если тип имеет один.
  • Рефлексия для сложного типа, имеющего свойства.

Примечание.

Привязка имеет несколько ограничений:

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

Иерархии привязки

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

{
  "Parent": {
    "FavoriteNumber": 7,
    "Child": {
      "Name": "Example",
      "GrandChild": {
        "Age": 3
      }
    }
  }
}

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

Ключ Значение
"Parent:FavoriteNumber" 7
"Parent:Child:Name" "Example"
"Parent:Child:GrandChild:Age" 3

Простой пример

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

Совет

Тип System.Configuration.ConfigurationBuilder отличается от Microsoft.Extensions.Configuration.ConfigurationBuilder типа. Все это содержимое относится к пакетам и пространствам имен NuGet Microsoft.Extensions.*.

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

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
  </ItemGroup>

</Project>

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

Рассмотрим пример файла appsettings.json:

{
    "Settings": {
        "KeyOne": 1,
        "KeyTwo": true,
        "KeyThree": {
            "Message": "Oh, that's nice...",
            "SupportedVersions": {
                "v1": "1.0.0",
                "v3": "3.0.7"
            }
        },
        "IPAddressRange": [
            "46.36.198.121",
            "46.36.198.122",
            "46.36.198.123",
            "46.36.198.124",
            "46.36.198.125"
        ]
    }
}

Теперь, учитывая этот JSON-файл, ниже приведен пример шаблона потребления с помощью построителя конфигураций напрямую:

using Microsoft.Extensions.Configuration;

// Build a config object, using env vars and JSON providers.
IConfigurationRoot config = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .AddEnvironmentVariables()
    .Build();

// Get values from the config given their key and their target type.
Settings? settings = config.GetRequiredSection("Settings").Get<Settings>();

// Write the values to the console.
Console.WriteLine($"KeyOne = {settings?.KeyOne}");
Console.WriteLine($"KeyTwo = {settings?.KeyTwo}");
Console.WriteLine($"KeyThree:Message = {settings?.KeyThree?.Message}");

// Application code which might rely on the config could start here.

// This will output the following:
//   KeyOne = 1
//   KeyTwo = True
//   KeyThree:Message = Oh, that's nice...

В приведенном выше коде C#:

  • Создает экземпляр ConfigurationBuilder.
  • Добавляет файл "appsettings.json" для распознавания поставщиком конфигурации JSON.
  • Добавляет переменные среды для распознавания поставщиком конфигурации с переменными среды.
  • Возвращает обязательный "Settings" раздел и соответствующий Settings экземпляр с помощью экземпляра config .

Объект Settings имеет следующий вид:

public sealed class Settings
{
    public required int KeyOne { get; set; }
    public required bool KeyTwo { get; set; }
    public required NestedSettings KeyThree { get; set; } = null!;
}
public sealed class NestedSettings
{
    public required string Message { get; set; } = null!;
}

Простой пример с размещением

Чтобы получить доступ к значению IConfiguration, вы можете снова использовать пакет NuGet Microsoft.Extensions.Hosting. Создайте новое консольное приложение и вставьте в него следующее содержимое файла проекта:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
  </ItemGroup>

</Project>

Предыдущий файл проекта определяет следующее:

  • Приложение — это исполняемый файл.
  • Файл appsettings.json должен быть скопирован в выходной каталог при компиляции проекта.
  • Microsoft.Extensions.Hosting Добавлена ссылка на пакет NuGet.

Добавьте файл appsettings.json в корень проекта со следующим содержимым:

{
    "KeyOne": 1,
    "KeyTwo": true,
    "KeyThree": {
        "Message": "Thanks for checking this out!"
    }
}

Замените содержимое файла Program.cs следующим кодом C#:

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

using IHost host = Host.CreateApplicationBuilder(args).Build();

// Ask the service provider for the configuration abstraction.
IConfiguration config = host.Services.GetRequiredService<IConfiguration>();

// Get values from the config given their key and their target type.
int keyOneValue = config.GetValue<int>("KeyOne");
bool keyTwoValue = config.GetValue<bool>("KeyTwo");
string? keyThreeNestedValue = config.GetValue<string>("KeyThree:Message");

// Write the values to the console.
Console.WriteLine($"KeyOne = {keyOneValue}");
Console.WriteLine($"KeyTwo = {keyTwoValue}");
Console.WriteLine($"KeyThree:Message = {keyThreeNestedValue}");

// Application code which might rely on the config could start here.

await host.RunAsync();

// This will output the following:
//   KeyOne = 1
//   KeyTwo = True
//   KeyThree:Message = Thanks for checking this out!

При запуске этого приложения Host.CreateApplicationBuilder определит поведение для обнаружения конфигурации JSON и предоставления доступа к ней через экземпляр IConfiguration. Из экземпляра host вы можете обратиться к поставщику службы для предоставления экземпляра IConfiguration и его значений.

Совет

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

Базовый пример размещения и использования API индексатора

Рассмотрим то же appsettings.json содержимое файла из предыдущего примера:

{
    "SupportedVersions": {
        "v1": "1.0.0",
        "v3": "3.0.7"
    },
    "IPAddressRange": [
        "46.36.198.123",
        "46.36.198.124",
        "46.36.198.125"
    ]
}

Замените содержимое файла Program.cs следующим кодом C#:

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

using IHost host = Host.CreateApplicationBuilder(args).Build();

// Ask the service provider for the configuration abstraction.
IConfiguration config = host.Services.GetRequiredService<IConfiguration>();

// Get values from the config given their key and their target type.
string? ipOne = config["IPAddressRange:0"];
string? ipTwo = config["IPAddressRange:1"];
string? ipThree = config["IPAddressRange:2"];
string? versionOne = config["SupportedVersions:v1"];
string? versionThree = config["SupportedVersions:v3"];

// Write the values to the console.
Console.WriteLine($"IPAddressRange:0 = {ipOne}");
Console.WriteLine($"IPAddressRange:1 = {ipTwo}");
Console.WriteLine($"IPAddressRange:2 = {ipThree}");
Console.WriteLine($"SupportedVersions:v1 = {versionOne}");
Console.WriteLine($"SupportedVersions:v3 = {versionThree}");

// Application code which might rely on the config could start here.

await host.RunAsync();

// This will output the following:
//     IPAddressRange:0 = 46.36.198.123
//     IPAddressRange:1 = 46.36.198.124
//     IPAddressRange:2 = 46.36.198.125
//     SupportedVersions:v1 = 1.0.0
//     SupportedVersions:v3 = 3.0.7

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

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

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

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

Совет

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

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

См. также