Какая была архитектура сервиса и как располагали контроллер, бизнес-логику и слой данных
Что проверяют
Понимаете ли вы, зачем разводить HTTP, бизнес-правила и доступ к данным по разным местам, и умеете ли показать эти границы в своём проекте. Следом обычно спрашивают, где у вас живёт валидация, как устроены транзакции и нужен ли репозиторий поверх EF Core.
Как отвечать
Опишите реальную структуру решения на ASP.NET Core и направление зависимостей:
- контроллер или Minimal API: тонкий слой. Принимает DTO, возвращает
ActionResult<T>илиIResult, вызывает сервис и переводит результат в HTTP-код. С атрибутом[ApiController]невалидная модель сама даёт 400 сProblemDetails; - бизнес-логика: сервисы приложения или обработчики команд и запросов в духе CQRS. Здесь правила, инварианты, оркестрация. Слой ничего не знает про HTTP и не трогает
HttpContext; - доступ к данным:
DbContextиз EF Core уже реализует единицу работы, аDbSet<T>по сути репозиторий. Свои репозитории оправданы, когда нужно спрятать сложные запросы или хранилищ несколько; - связь слоёв: всё через DI.
AddDbContextрегистрирует контекст как scoped, сервисы обычно тоже scoped, чтобы на запрос приходился один контекст; - структура проектов: при Clean Architecture это Domain, Application, Infrastructure и Web. Интерфейсы объявлены в Application, реализации в Infrastructure, зависимости направлены внутрь.
Всё асинхронно, с CancellationToken от действия контроллера до ToListAsync(). Если в проекте были вертикальные срезы по фичам вместо горизонтальных слоёв, так и скажите и объясните, почему.
Где спотыкаются
Пишут бизнес-логику прямо в контроллере или, наоборот, заводят сервис, который только пробрасывает вызов в репозиторий. В первом случае логику не протестировать без HTTP, во втором слой есть, а смысла в нём нет.
Отдают сущности EF наружу вместо DTO. Отсюда лишние поля в ответе, циклические ссылки при сериализации и возможность через запрос переписать поле, которое клиент менять не должен.
Внедряют scoped-сервис или DbContext в синглтон. Получается захваченная зависимость: один контекст на все запросы и ошибки конкурентного доступа. В среде Development ASP.NET Core проверяет области видимости и бросает на этом исключение.