Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Настройка в .NET выполняется с помощью одного или нескольких поставщиков конфигурации . Поставщики конфигурации считывают данные конфигурации из пар ключ-значение через разные источники конфигурации.
- Файлы параметров, например appsettings.json
- Переменные среды
- Azure Key Vault
- Конфигурация приложений Azure
- Аргументы командной строки
- Пользовательские поставщики (установленные или созданные)
- Файлы каталогов
- Объекты .NET в памяти
- Сторонние поставщики
Заметка
Сведения о настройке самой среды выполнения .NET см. в параметрах конфигурации среды выполнения .NET.
Основные понятия и абстракции
Учитывая один или несколько источников конфигурации, тип IConfiguration предоставляет единое представление данных конфигурации. Конфигурация доступна только для чтения, и шаблон конфигурации не предназначен для программной записи. Интерфейс IConfiguration является одним представлением всех источников конфигурации, как показано на следующей схеме:
Настройка консольных приложений
Консольные приложения .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 Generic Host. Вместо этого добавьте ссылку на пакет📦 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.
Environment.json при использовании поставщика конфигурации JSON . Например, appsettings.appsettings Production.json и appsettings Development.json.. - appsettings.json с помощью поставщика конфигурации 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 |
Сценарии расширенной привязки
При работе с определенными типами привязка конфигурации имеет определенное поведение и ограничения. В этом разделе содержатся следующие подразделы:
- Привязка к словарям
- Ключи словаря с двоеточиями
- Привязка к типам IReadOnly*
- Связывание с параметризованными конструкторами
Привязка к словарям
При привязке конфигурации к Dictionary<TKey,TValue> месту, где значение является мутируемым типом коллекции (например, массивами или списками), повторяющиеся привязки к одному ключу расширяют значения коллекции вместо замены.
В следующем примере показано следующее поведение:
IConfiguration config = new ConfigurationBuilder()
.AddInMemoryCollection()
.Build();
config["Queue:0"] = "Value1";
var dict = new Dictionary<string, string[]>() { { "Queue", new[] { "InitialValue" } } };
Console.WriteLine("=== Dictionary Binding with Collection Values ===");
Console.WriteLine($"Initially: {string.Join(", ", dict["Queue"])}");
// In .NET 7+, binding extends the collection instead of replacing it.
config.Bind(dict);
Console.WriteLine($"After Bind: {string.Join(", ", dict["Queue"])}");
config["Queue:1"] = "Value2";
config.Bind(dict);
Console.WriteLine($"After 2nd Bind: {string.Join(", ", dict["Queue"])}");
Дополнительные сведения см. в разделе "Конфигурация привязки к словарю расширяет значения".
Ключи словаря с двоеточиями
Символ двоеточия (:) зарезервирован в качестве разделителя иерархии в ключах конфигурации. Это означает, что при настройке привязки нельзя использовать двоеточия в ключах словаря. Если ключи содержат двоеточия (например, URL-адреса или другие форматированные идентификаторы), система конфигурации интерпретирует их как пути иерархии, а не литеральные символы. Рассмотрим следующие обходные пути.
- Используйте альтернативные символы разделителя (например, двойные подчеркивания
__) в ключах конфигурации и при необходимости преобразуйте их программным способом. - Вручную десериализуйте конфигурацию как сырой JSON с помощью System.Text.Json или аналогичной библиотеки, поддерживающей двоеточия в ключах.
- Создайте пользовательский слой сопоставления, который преобразует безопасные ключи в необходимые ключи, используя двоеточия.
Привязка к типам IReadOnly*
Привязка конфигурации не поддерживает привязку непосредственно к интерфейсам коллекций IReadOnlyList<T>, IReadOnlyDictionary<TKey, TValue> или другим интерфейсам коллекций только для чтения. Этим интерфейсам не хватает механизмов, необходимых привязке для заполнения коллекций.
Чтобы работать с коллекциями только для чтения, используйте изменяемые типы для свойств, заполняемых привязкой, а затем предоставляйте их как интерфейсы только для чтения для потребителей:
Console.WriteLine("=== IReadOnly* Types (NOT Directly Supported) ===");
var readonlyConfig = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["Settings:Values:0"] = "Item1",
["Settings:Values:1"] = "Item2",
["Settings:Values:2"] = "Item3",
})
.Build();
// This class uses List<string> for binding, exposes as IReadOnlyList<string>.
var settings = new SettingsWithReadOnly();
readonlyConfig.GetSection("Settings").Bind(settings);
Console.WriteLine("Values bound to mutable List, exposed as IReadOnlyList:");
foreach (var value in settings.ValuesReadOnly)
{
Console.WriteLine($" {value}");
}
Реализация класса конфигурации:
class SettingsWithReadOnly
{
// Use mutable type for binding
public List<string> Values { get; set; } = [];
// Expose as read-only for consumers
public IReadOnlyList<string> ValuesReadOnly => Values;
}
Этот подход позволяет связывателю заполнять изменяемый List<string>, при показе неизменяемого интерфейса потребителям через IReadOnlyList<string>.
Привязка с параметризуемыми конструкторами
Начиная с .NET 7, привязчик конфигурации поддерживает привязку к типам с одним общедоступным параметризованным конструктором. Это позволяет заполнять неизменяемые типы и записи непосредственно из конфигурации:
Console.WriteLine("=== Parameterized Constructor Binding ===");
var ctorConfig = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["AppSettings:Name"] = "MyApp",
["AppSettings:MaxConnections"] = "100",
["AppSettings:Timeout"] = "30"
})
.Build();
// Binding to a type with a single parameterized constructor
var appSettings = ctorConfig.GetSection("AppSettings").Get<AppSettings>();
if (appSettings != null)
{
Console.WriteLine($"Name: {appSettings.Name}");
Console.WriteLine($"MaxConnections: {appSettings.MaxConnections}");
Console.WriteLine($"Timeout: {appSettings.Timeout}");
}
Класс неизменяемых параметров:
// Immutable type with single parameterized constructor.
class AppSettings
{
public string Name { get; }
public int MaxConnections { get; }
public int Timeout { get; }
public AppSettings(string name, int maxConnections, int timeout)
{
Name = name;
MaxConnections = maxConnections;
Timeout = timeout;
}
}
Это важно
Привязыватель поддерживает только типы с одним общедоступным параметризованным конструктором. Если тип имеет несколько открытых параметризованных конструкторов, привязка не может определить, какой из них следует использовать, и привязка завершится ошибкой. Используйте один параметризованный конструктор или конструктор без параметров с помощью наборов свойств.
Базовый пример
Чтобы получить доступ к значениям конфигурации в их базовой форме, без помощи подхода универсального узла, используйте тип ConfigurationBuilder напрямую.
Совет
Тип System.Configuration.ConfigurationBuilder отличается от типа Microsoft.Extensions.Configuration.ConfigurationBuilder. Всё это содержимое относится к пакетам и пространствам имен Microsoft.Extensions.* NuGet.
Рассмотрим следующий проект C#:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.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="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.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>net10.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="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.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