Конфігурація в ASP.NET Core: Основи
Конфігурація в ASP.NET Core: Основи
Будь-якому додатку потрібні налаштування. Рядки підключення до бази даних (Connection Strings), секретні ключі для JWT-токенів, адреси сторонніх API, таймаути чи навіть просто увімкнення режиму "технічних робіт" — усе це не можна тримати "захардкодженим" (hardcoded) прямо в C#.
Код має залишатися кодом, а налаштування повинні змінюватися залежно від середовища (Development для вашого ноутбука, Production для реального сервера).
В ASP.NET Core є потужна, гнучка і стандартизована система для роботи з налаштуваннями на базі інтерфейсу IConfiguration.
Джерела конфігурації (Configuration Sources)
Система конфігурації ASP.NET Core працює за принципом словника (Dictionary), де кожне налаштування має свій ключ і значення (key => value).
Але звідки беруться ці ключі? Фреймворк вміє читати дані з багатьох джерел одночасно:
- Файли
appsettings.jsonта створюваний спеціально для вашого середовищаappsettings.{Environment}.json(наприклад,appsettings.Development.json). - Змінні середовища (Environment variables).
- Аргументи командного рядка (Command-line arguments).
- Інші формати файлів: INI, XML.
- Менеджери секретів (Azure Key Vault, AWS Secrets Manager, User Secrets для локальної розробки).
За замовчуванням WebApplication.CreateBuilder(args) автоматично підключає пункти 1, 2 і 3. Вам не потрібно писати для цього жодного рядка коду!
Читання базових налаштувань
Уявіть, що у вас є файл appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"MyCustomApplicationName": "SuperShop",
"Database": {
"ConnectionString": "Server=myServer;Database=myDb;"
}
}
Ви можете отримати ці значення прямо під час налаштування програми або всередині ваших кінцевих точок (Endpoints):
var builder = WebApplication.CreateBuilder(args);
// Читання на етапі ініціалізації (найпростіший ключ)
var appName = builder.Configuration["MyCustomApplicationName"];
Console.WriteLine($"Starting app: {appName}"); // Виведе: Starting app: SuperShop
var app = builder.Build();
// Читання вкладених ключів в маршруті за допомогою символу двокрапки ':'
app.MapGet("/db-info", (IConfiguration config) =>
{
var connString = config["Database:ConnectionString"];
return $"We are connecting to: {connString}";
});
app.Run();
Анатомія коду:
- В об'єкті
builder.Configurationлежать усі склеєні разом налаштування зі всіх джерел. - Щоб дістатися до вкладеного поля в JSON (
Database->ConnectionString), ми використовуємо "шлях" з двокрапкою:"Database:ConnectionString". Це стандартний роздільник у всьому ASP.NET Core. - В лямбді для маршруту ми інжектували
IConfiguration. Цей інтерфейс доступний "з коробки" у системі Dependency Injection, тому його можна просити будь-де в програмі (у сервісах, роутах тощо).
Пріоритет (Перевизначення)
Оскільки джерел багато, що буде, якщо одне і те ж налаштування вказано в кількох місцях? Система працює за правилом "хто останній, той і правий".
Дефолтний порядок завантаження (від найнижчого пріоритету до найвищого):
appsettings.jsonappsettings.{Environment}.json(наприклад,appsettings.Production.json)- User Secrets (лише в режимі розробника)
- Змінні середовища системи (Environment Variables)
- Аргументи командного рядка.
Практичний приклад:
Ви написали в appsettings.json:
"Database:ConnectionString": "Server=localhost;"
Ви запускаєте програму на Linux сервері, і системний адміністратор передає змінну середовища:
Database__ConnectionString=Server=prod-db.amazon.com; (в Linux замість двокрапки використовується подвійне підкреслення __ для вкладеності).
В момент звернення до config["Database:ConnectionString"] програма отримає Server=prod-db.amazon.com;, тому що змінні середовища завантажуються пізніше і перезаписують значення з JSON-файлу. Це робить деплой на сервери максимально зручним!
Додавання нових джерел (Custom Providers)
Ви не обмежені вбудованими форматами. Уявімо сітуацію, коли у вас є стара бухгалтерська програма, яка вивантажує налаштування в звичайний файл config.txt у форматі КЛЮЧ=ЗНАЧЕННЯ. Ви можете додати читання цього файлу до вашого builder.Configuration!
Щоб розпочати читати свої формати (або брати старі INI чи XML), ми модифікуємо колекцію провайдерів:
var builder = WebApplication.CreateBuilder(args);
// Якщо у нас вже є підключені за замовчуванням (JSON, EnvVars) - ми залишаємо їх
// та просто додаємо щось нове:
builder.Configuration.AddIniFile("legacy-settings.ini", optional: true, reloadOnChange: true);
builder.Configuration.AddXmlFile("enterprise-config.xml", optional: true);
var app = builder.Build();
// ...
Анатомія коду:
.AddIniFileта.AddXmlFileзавантажують налаштування з інших файлів поверх уже завантаженихappsettings.json.- Параметр
optional: trueозначає, що якщо файлу немає на диску, програма не "впаде" зFileNotFoundException, а просто проігнорує цей провайдер. - Параметр
reloadOnChange: true— магія! Якщо ви зміните цей INI-файл у Блокноті під час роботи сервера, конфігурація автоматично оновить значення у пам'яті без перезапуску програми!
Практичні завдання
appsettings.json з текстом "Greeting": "Hello from JSON".
Ви запускаєте програму через консоль командою:
dotnet run --Greeting "Hello from Console"
Крім того, у вас в ОС встановлена змінна середовища Greeting="Hello from Environment".
Що виведе Console.WriteLine(builder.Configuration["Greeting"]); при старті додатка? Поясніть чому.Urls (зверніть увагу, з великої літери).
Спробуйте запустити додаток з командного рядка, передавши йому кастомні порти (наприклад 7777 для HTTP), не змінюючи appsettings.json та launchSettings.json.
Підказка: dotnet run --назва_ключа значенняСтатичні Активи: MapStaticAssets (ASP.NET Core 9.0)
Впродовж багатьох років в ASP.NET Core стандартом для роздачі файлів був підхід із UseStaticFiles(), який ми розглянули в попередньому розділі. Він працює добре: браузер запитує файл з папки wwwroot, сервер його знаходить (якщо він є) і відправляє.
Конфігурація: Паттерн Options
У попередньому розділі ми дізналися, що можемо діставати будь-яке налаштування просто викликавши config["Ключ:ВкладенийКлюч"].