Какие связи существуют между слоями integration и application в слоистой архитектуре
Что проверяют
Понимаете ли вы направление зависимостей между слоями и где проходит граница с внешним миром. Следом обычно просят показать это в решении .NET: какие проекты, кто на кого ссылается и где регистрируются реализации.
Как отвечать
Application это слой сценариев вроде «оформить заказ», он опирается на доменную модель. Integration (во многих шаблонах Infrastructure) общается с внешним миром: база, брокер, HTTP-API партнёров, почта, хранилище файлов.
Главная связь строится на инверсии зависимостей:
- интерфейсы объявляет Application:
IPaymentGateway,IOrderRepository, в терминах своей задачи, а не внешнего API; - реализации лежат в Integration:
HttpPaymentGatewayнаHttpClient, репозиторий на EF Core. Integration ссылается на Application, обратной ссылки нет; - сборка в composition root: в
Program.csчерезAddScoped<IPaymentGateway, HttpPaymentGateway>()или типизированный клиентAddHttpClient<...>(); - модели не протекают: DTO внешнего API и
HttpResponseMessageостаются внутри Integration, наружу уходят собственные типы. Это и есть антикоррупционный слой; - ошибки переводятся:
HttpRequestExceptionили таймаут превращаются в понятное Application исключение илиResult, и сценарий решает, повторять, откатывать или сообщать пользователю; - устойчивость живёт в Integration: повторы и circuit breaker через
Microsoft.Extensions.Http.Resilienceили Polly, а не циклыtry/catchв сценариях.
Если интеграция асинхронная, Application публикует событие через абстракцию, а Integration доставляет его в брокер, например через MassTransit с outbox.
Тесты Application идут с заглушками интерфейсов, а направление зависимостей фиксируют архитектурные тесты на NetArchTest.
Где спотыкаются
Рисуют стрелку от Application к Integration. Тогда сценарии зависят от EF Core и конкретного HTTP-клиента, и их не протестировать без базы и сети.
Кладут интерфейсы в проект Integration рядом с реализацией. Формально абстракция есть, но зависимость по-прежнему направлена наружу.
Пробрасывают DTO внешнего сервиса до контроллера. Любое изменение чужого контракта ломает всё приложение, а не один адаптер.