Структура проекта
Анатомия проекта: Program.cs, csproj, appsettings.json — где что лежит и зачем.
Суть: сердце приложения ASP.NET Core — файл
Program.cs, где собирается приложение и настраивается конвейер обработки запросов. Конфигурация хранится вappsettings.json, а зависимости и метаданные — в.csproj.
В современных версиях (.NET 6+) проект стал предельно компактным. Нет больше отдельных Startup.cs и громоздкого Main — благодаря top-level statements весь старт умещается в один файл. Разберём его.
Program.cs — точка входа
var builder = WebApplication.CreateBuilder(args);
// 1. Регистрация сервисов в DI-контейнере
builder.Services.AddControllers();
var app = builder.Build();
// 2. Настройка конвейера middleware
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Здесь два чётких этапа. До Build() — мы регистрируем сервисы (что приложение умеет: контроллеры, БД, аутентификация). После Build() — настраиваем конвейер: как именно обрабатывать каждый запрос. app.Run() запускает сервер и блокирует поток до остановки.
Структура папок
MyApi/
+-- Program.cs точка входа и сборка
+-- MyApi.csproj зависимости, версия .NET
+-- appsettings.json конфигурация (строки подключения и т.п.)
+-- appsettings.Development.json переопределение для dev
+-- Controllers/ контроллеры (если MVC-стиль)
+-- Properties/
+-- launchSettings.json настройки запуска (порты, профили)
Как работает под капотом
Файл .csproj — это XML, описывающий проект: какую версию .NET использовать (TargetFramework), какие NuGet-пакеты подключены. Когда вы делаете dotnet add package, в csproj добавляется строчка <PackageReference>. Конфигурация читается слоями: сначала appsettings.json, потом appsettings.{Environment}.json (например Development), потом переменные окружения — каждый следующий слой переопределяет предыдущий. Это позволяет хранить общие настройки в одном файле, а секреты и dev-специфику — отдельно.
Частые ошибки
- Класть секреты (пароли, ключи) прямо в appsettings.json. Их видно в git. Для dev используют User Secrets, для прода — переменные окружения или хранилища секретов.
- Менять порядок middleware наугад. Порядок строк после
Build()критичен — об этом отдельный раздел. - Путать appsettings.json и launchSettings.json. Первый — конфигурация приложения, второй — только локальные настройки запуска (в проде не используется).
Best practices
- Держите
Program.csчистым: выносите длинную настройку в extension-методы (builder.Services.AddMyServices()). - Чувствительные настройки читайте через
IConfiguration/IOptions, а не хардкодьте. - Среда (Development/Staging/Production) задаётся переменной
ASPNETCORE_ENVIRONMENT— используйте её для разного поведения.
Окружения и почему их три
ASP.NET Core из коробки знает про окружения: Development, Staging, Production. Текущее берётся из переменной ASPNETCORE_ENVIRONMENT. От него зависит многое: в Development показываются подробные страницы ошибок и включается Swagger, в Production — лаконичные ответы и строгие настройки. Это позволяет одному и тому же коду вести себя по-разному в зависимости от того, где он запущен, без правки исходников.
Конфигурация устроена как стопка слоёв-провайдеров, и порядок важен: базовый appsettings.json переопределяется файлом окружения (appsettings.Production.json), затем переменными окружения, затем аргументами командной строки. Последний слой всегда побеждает. Благодаря этому в проде секреты и адреса БД подставляются через переменные окружения контейнера, не трогая закоммиченные файлы.
Как читать конфигурацию правильно
Доступ к настройкам идёт через сервис IConfiguration, но напрямую обращаться к нему по строковым ключам — не лучший стиль. Предпочтительный путь — паттерн Options: вы заводите класс настроек, привязываете к нему секцию конфигурации и получаете типизированный объект через DI. Это даёт автодополнение, проверку типов и одно место, где видно, какие настройки вообще есть у компонента.
Секреты в разработке хранят в User Secrets — отдельном файле вне репозитория, привязанном к проекту. Команда dotnet user-secrets set кладёт туда значение, и оно автоматически подмешивается в конфигурацию в Development. В проде эту роль берут переменные окружения или специализированные хранилища (Azure Key Vault, HashiCorp Vault). Главное правило неизменно: ключи и пароли никогда не попадают в git.
Итог: Program.cs собирает приложение в два этапа (сервисы и конвейер), конфигурация лежит слоями в appsettings, а зависимости — в csproj. Теперь напишем первый эндпоинт.