Выбор архитектуры и стека .NET под сценарий
Перед выбором микросервисов, Clean Architecture или Blazor полезно зафиксировать три вещи:
- что строим (admin, магазин, API для мобилки);
- сколько людей в команде и как часто релизы;
- какие NFR (non-functional requirements) — нагрузка, задержка, аудит, доступность.
Общая теория проектирования — раздел 7-06. Принципы SOLID — 1112. Маршрут обучения — 475.
Монолит — одно развёртываемое приложение (один процесс или один контейнер). Микросервисы — несколько независимых сервисов с отдельными деплоями. Стартовая рекомендация для большинства учебных и малых коммерческих проектов — монолит с чёткими слоями, пока нет измеримой боли (разные команды, частые независимые релизы, узкое место по масштабу). Подробнее — микросервисы.
Схема выбора
1. Внутренний admin и back-office
Панель для сотрудников: справочники, отчёты, ручное редактирование данных.
UI
- Razor Pages — страницы с HTML на сервере, проще для CRUD.
- Blazor Server — интерактивный UI без отдельного JavaScript-фреймворка.
Аутентификация
- Cookie и роли через Identity.
- Пользователи внутри компании, браузер хранит сессию.
База данных
- EF Core — первая программа.
- SQL Server или PostgreSQL — практика SQL.
Структура кода
- Классический N-слой (UI → сервисы → данные) или упрощённый Clean Architecture.
- MediatR — по желанию, когда сценариев становится много.
На первом этапе обычно не нужны
- Kubernetes
- GraphQL
- Event sourcing
2. Публичный REST API и backend для мобильного приложения
Сервер отдаёт JSON по HTTP; клиенты — мобильные приложения, SPA, партнёры.
Фреймворк
- ASP.NET Core Web API
- Minimal API для небольших сервисов
Контракт
- OpenAPI (Swagger) для документации.
- Версионирование через URL (
/v1/...) или заголовок.
Надёжность и безопасность
Данные
- EF Core; при росте нагрузки — продвинутые темы EF
Итог по стеку
- API без состояния на сервере между запросами — проще масштабировать горизонтально.
- JSON и OpenAPI задают понятный контракт для мобильных и внешних клиентов.
HTTP-основа — 118.
3. Интернет-магазин (малый и средний)
Стартовая структура
- Модульный монолит с зонами Catalog, Cart, Orders, Payments.
- Один репозиторий, один деплой, границы — папки или проекты в solution.
Транзакции и оплата
- EF + явные границы транзакций.
- Webhook оплаты с идемпотентностью (повторный запрос не создаёт второй заказ) — интеграции.
Фоновые задачи
IHostedServiceдля простых сценариев.- Брокер сообщений (RabbitMQ, Azure Service Bus) при пиках нагрузки.
Кэш
IDistributedCacheс Redis для каталога.
Масштабирование позже
- Read replicas
- Проекции для чтения
- Выделение сервисов — только при отдельных командах и метриках
См. пакетная работа с данными.
4. Real-time (чат, дашборд, уведомления)
Протокол
- SignalR поверх WebSocket или long polling.
Масштаб кластера
- Redis backplane или Azure SignalR Service — чтобы несколько инстансов API видели одни hub-подключения.
Разделение обязанностей
- REST — история сообщений, профили.
- Hub — live-события.
Auth
- JWT в query string или заголовке при установке WebSocket.
5. SaaS B2B multi-tenant
Несколько организаций-клиентов в одном продукте.
Изоляция данных
- Колонка
TenantIdв строках — типичный старт. - Отдельная схема или БД на tenant — реже, при жёстких требованиях.
Auth
- OIDC (OpenID Connect) — Identity, auth в ASP.NET.
Конфигурация
- Options pattern на tenant.
Аудит
- Структурированные логи, correlation id — платформа .NET.
Рост
- Billing и Notifications выносят в отдельные сервисы, когда над ними работает отдельная команда.
6. CLI, serverless и edge
Холодный старт и размер
- Native AOT
- Trim, минимум рефлексии
Данные
- Dapper часто легче EF для узких утилит.
7. Desktop (WinForms, WPF, MAUI)
- WinForms и WPF — десктопные приложения, Lab 1138
- Кроссплатформа — MAUI
- MVVM — отдельная ViewModel, без EF прямо в коде окна
8. Игры (Unity)
Маршрут — C# для Unity. ASP.NET на первом проходе можно отложить.
Паттерны и когда их подключать
| Паттерн | Подходит, если | Рано подключать, если |
|---|---|---|
| Clean Architecture | 3+ разработчика, долгий жизненный цикл | Pet-проект на 2 недели |
| CQRS + MediatR | Много use-case, общие pipeline (валидация, лог) | 5 CRUD-эндпоинтов |
| Repository поверх EF | Сложные запросы, подмена в тестах | Generic IRepository<T> без логики |
| Event Sourcing | Нужен аудит и replay событий | Обычный CRUD |
| Микросервисы | Независимые релизы, разные команды | Нет DevOps и метрик |
Паттерны проектирования, декомпозиция монолита.
Частые ошибки
- Микросервисы "на вырост" без CI/CD и мониторинга — растёт сложность, выгода откладывается.
- Blazor WebAssembly для простого admin — лишний фронтенд-стек; Razor Pages проще.
- EF без базового SQL — N+1 и тяжёлые миграции; см. 443, SQL.
- GraphQL без причины (overfetch редок) — усложняется кэш; REST часто достаточен — бэкенд.
Краткая шпаргалка
| Сценарий | dotnet new | Статьи |
|---|---|---|
| API | webapi | 4511, 4519, 443 |
| Admin | razor или blazorserver | 4514, 4512 |
| Консоль + БД | console + EF | 441 |
| Real-time | webapi + SignalR | 2 |
| AOT CLI | console + PublishAot | 191 |