Какая библиотека для IoC контейнера использовалась
Что проверяют
Понимаете ли вы, зачем нужен контейнер внедрения зависимостей и что он даёт кроме модной архитектуры. Название библиотеки здесь повод поговорить о жизненных циклах, тестах и цене магии. Следом обычно спрашивают, как вы подменяли зависимость в тестах и сталкивались ли с циклическими зависимостями.
Как отвечать
Назовите, что использовали, и объясните выбор. Основные варианты в Node.js:
- NestJS: встроенный контейнер, самый частый случай. Провайдеры регистрируются в модулях и внедряются через конструктор, области видимости
DEFAULT(синглтон),REQUESTиTRANSIENT. ОбластьREQUESTподнимается вверх по цепочке зависимостей и создаёт объекты на каждый запрос, это заметно по производительности; - InversifyJS: декораторы
@injectable()и@inject(), привязки черезcontainer.bind(), обычно нуженreflect-metadataи включённыеexperimentalDecoratorsсemitDecoratorMetadata; - Awilix: без декораторов, зависимости разрешаются по именам, жизненные циклы
SINGLETON,SCOPED,TRANSIENT, удобно создавать дочерний scope на HTTP-запрос. Работает и в чистом JavaScript; - без контейнера: ручная сборка в одной точке входа (composition root) через фабрики и параметры конструктора. Для небольшого сервиса это честный и понятный вариант.
Дальше расскажите, что это дало: в тестах зависимость заменяется через Test.createTestingModule().overrideProvider() в Nest или повторной регистрацией в Awilix.
Полезная деталь: стандартные декораторы TypeScript 5 не поддерживают декораторы параметров и не генерируют метаданные типов, поэтому Nest и Inversify работают на старом режиме experimentalDecorators. esbuild эти метаданные не выпускает, и тесты Nest под Vitest запускают через плагин SWC.
Где спотыкаются
Превращают контейнер в сервис-локатор и вызывают container.get() в глубине кода. Зависимости снова скрыты, и тестировать не легче, чем без DI.
Лечат циклические зависимости через forwardRef() вместо того, чтобы вынести общую логику в третий сервис.
Путают IoC и DI. Инверсия управления это принцип, внедрение зависимостей один из способов его реализовать, а контейнер лишь инструмент для него.