Настройка в .NET
Настройка в .NET выполняется с помощью одного или нескольких поставщиков конфигурации . Поставщики конфигурации считывают данные конфигурации из пар "ключ-значение", используя различные источники конфигурации:
- Файлы параметров, например appsettings.json
- Переменные среды
- Azure Key Vault
- Конфигурация приложений Azure
- Аргументы командной строки
- Настраиваемые провайдеры, установленные или созданные
- Файлы каталогов
- Объекты .NET в памяти
- Сторонние поставщики
Заметка
Сведения о настройке самой среды выполнения .NET см. в параметрах конфигурации среды выполнения .NET.
Основные понятия и абстракции
Учитывая один или несколько источников конфигурации, тип 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[]) предоставляет конфигурацию по умолчанию для приложения в следующем порядке: от самого высокого до низкого приоритета:
- Аргументы командной строки с помощью поставщика конфигурации командной строки .
- Переменные среды с использованием поставщика конфигурации "Переменные среды" .
-
секреты приложений при запуске приложения в среде
Development
. - appsettings.json с помощью поставщика конфигурации JSON.
-
appsettings.
Environment
.json при использовании поставщика конфигурации JSON . Например, appsettings.appsettings Production.json и appsettings Development.json.. -
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.
-
Microsoft.Extensions.Configuration.Binder: функциональные возможности привязки объекта к данным в поставщиках конфигураций для
Microsoft.Extensions.Configuration
. -
Microsoft.Extensions.Configuration.Json: реализация поставщика конфигурации JSON для
Microsoft.Extensions.Configuration
. -
Microsoft.Extensions.Configuration.EnvironmentVariables: реализация поставщика конфигурации для переменных среды
Microsoft.Extensions.Configuration
.
Рассмотрим пример файла 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.
См. также
- поставщики конфигурации в .NET
- Внедрение пользовательского поставщика конфигурации
- Ошибки конфигурации должны быть созданы в репозитории github.com/dotnet/runtime
- Конфигурация в ASP.NET Core