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


Настройка в .NET

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

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

Заметка

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

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

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

Интерфейс IConfiguration является одним представлением всех источников конфигурации.

Настройка консольных приложений

Консольные приложения .NET, созданные с помощью шаблона команд dotnet dotnet new или 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.appsettings Production.json и appsettings Development.json..
  6. ChainedConfigurationProvider: добавляет существующий IConfiguration в качестве источника.

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

Привязка

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

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

  • IConfiguration: представляет набор свойств конфигурации приложения key/value.
  • 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. Всё это содержимое относится к пакетам и пространствам имен Microsoft.Extensions.* NuGet.

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

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

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

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

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.3" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.3" />
  </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.Configuration.Binder" Version="9.0.3" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
  </ItemGroup>

</Project>

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

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

Добавьте файл 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.

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

Совет

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

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

См. также