Talanto
For recruiters
PlansCV Review
Login

Categories

  • All articles
  • Job Search
  • Resume & CV
  • Cover Letters & Applications
  • Interviews
  • Salary & Offers
  • Job Reviews & Roundups
  • Remote Work
  • Career
  • Career Growth
  • Market Trends
  • Onboarding
  • Tips

Related articles

  • Как готовиться к собеседованиям системно

    7d ago

  • Тайм-менеджмент для поиска работы при загруженности

    19d ago

  • Как не выгореть во время долгого поиска работы

    30d ago

  • Синдром самозванца у разработчиков: что с ним делать

    42d ago

  • Уведомления о вакансиях в Telegram и LinkedIn: как откликаться раньше

    54d ago

Looking for a job?

IT roles with remote and relocation options.

Browse jobs
  1. Articles
  2. Tips

Dependency Injection: шов для теста, не культ контейнера

DI — не Spring в шапке резюме. Ниже — зачем зависимость приходит снаружи, чем конструктор честнее локатора и когда ручная склейка лучше фреймворка. Пять букв SOLID — в соседнем гайде. Блоков кода нет: на экране просят ваш сервис.

9 min readJune 14, 2026193 views

On this page
  1. Боль: жёсткая склейка, не отсутствие фреймворка
  2. Конструктор, а не магия полей
  3. Пример 1. Заказы и почта
  4. Пример 2. Созвон «у нас Nest, значит умею DI»
  5. Контейнер, service locator, ручная склейка
  6. Где DI вреден
  7. Тест как проверка, что шов не для галочки
  8. Резюме и грейд
  9. Языки разные, шов один
  10. Частые вопросы
  11. Что сделать сейчас

Dependency Injection на созвоне часто звучит как Spring и «контейнер сам всё проставит». На деле это скучная развилка: сервис заказа сам делает new Postgres или получает уже готовое хранилище снаружи. Вторая схема дешевле меняется и тестируется. Контейнер — опция. Буква D в SOLID — тот же шов, только в алфавите: подробности принципов в чистой архитектуре и SOLID, здесь не повторяю пять букв.

Ниже — зачем шов, чем конструктор отличается от «достать из глобального локатора», когда ручная склейка честнее фреймворка, и как не написать DI в шапке резюме без теста без сети. Блоков кода нет специально: на экране просят ваш сервис, не учебный сниппет.

Коротко:

  • Зависимость приходит снаружи. Класс не знает, Postgres это или фейк в тесте.
  • Конструктор — обычный шов. Сеттер и «поле, которое кто-то потом заполнит» хуже читаются.
  • Контейнер (Spring, Nest, FastAPI Depends) автоматизирует склейку. Он не заменяет шов: без шва контейнер только прячет new в XML/декораторах.
  • Маленький скрипт и пет из трёх эндпоинтов часто дешевле собирать руками. Фреймворк ради «как во взрослых» — долг.
  • В CV нужен тест без сети и замена шлюза, не слово «DI». Пули: опыт.

Боль: жёсткая склейка, не отсутствие фреймворка

Сервис оплаты внутри конструктора создаёт клиент банка, логгер и почту. Тест либо ходит в банк, либо не пишется. Смена провайдера — правка того же класса. Ревьюер не видит, что тестировать. Это связанность, не «мало паттернов».

DI не про красоту. Про стоимость замены и про тест за доли секунды. Если за год шлюз не меняли и теста нет — сначала тест с фейком, потом разговор про контейнер. Иначе вы перенесёте new в конфиг и назовёте это архитектурой. Тот же критерий, что на ревью SOLID: называйте изменение, которое уже болело, не букву паттерна.

Связь с чистой архитектурой: ядро не импортирует драйвер. DI — способ это соблюсти на уровне объекта. Папки domain/infra без шва в конструкторе — декорации. Рекрутер откроет репозиторий и увидит слои без рабочего сценария — это слабее одного теста без сети. Для входа без стажа сценарий важнее графа зависимостей: резюме без опыта.

Конструктор, а не магия полей

Самый скучный рабочий вариант: в конструктор передали хранилище, очередь, часы. В проде — боевые. В тесте — фейки, которые запоминают вызовы. Часы тоже зависимость, если пишете «сейчас»: иначе тесты плавают по понедельникам. Генератор id и «случайность» — тот же приём: не прячьте их внутри, если от них зависит ветка сценария.

Сеттер-инъекция: объект существует «полусобранным», пока кто-то не вызвал setDb. Легко забыть. На созвоне это видно по пустой ссылке в середине сценария. Свойства, которые контейнер заполняет рефлексией, удобны фреймворку и непрозрачны человеку. Предпочитайте явный конструктор, пока команда не договорилась иначе. Если фреймворк настаивает на сеттерах — соберите объект полностью до первого вызова бизнес-метода, не «поле заполнится потом».

Интерфейс нужен, когда есть две реализации или тест. Интерфейс «на будущее» с одной реализацией — шум, это уже в SOLID. Для DI достаточно роли: «то, что умеет сохранить заказ». Имя роли важнее слова Interface в файле. Не плодите IOrderService и OrderServiceImpl, если impl один и имя ничего не говорит.

Пример 1. Заказы и почта

Было: сервис считает сумму, сам ходит в Postgres, сам шлёт SMTP. Тест поднимает Docker. CI красный без VPN.

Стало. Сервис принимает «хранилище» и «уведомитель». Считает сумму сам. В тесте хранилище — список в памяти, уведомитель считает письма и никуда не стучится. Боевая склейка — один файл рядом с точкой входа, не внутри домена. Сменили SMTP на очередь — правка склейки, тесты суммы зелёные. Это DI без Spring. Если потом появится контейнер, он соберёт те же роли.

Не выносите расчёт суммы в «сервис ради сервиса». Шов там, где уже жгло: почта, база, чужой HTTP. Расчёт, который меняется вместе с правилами заказа, может жить в том же классе, пока правил мало.

Пример 2. Созвон «у нас Nest, значит умею DI»

Игорь в CV: «NestJS, Dependency Injection, SOLID». На экране просят: как протестировать сервис без Mongo. Он открывает модуль с декораторами и не может подставить фейк без подъёма всего приложения.

Что сказать. «Сервис получает репозиторий конструктором. В юните — фейк с двумя заказами. В интеграционном — контейнер с тестовой базой, один сценарий». Если юнита нет и всё только e2e — честно так и скажите: шов бумажный, контейнер есть. Тогда не пишите DI в шапке. Напишите Nest и поставку. Шаблон рассказа: как в SOLID-созвоне, только про одну зависимость, не про пять букв.

Фреймворк, который «сам проставляет», не учит шву. Учит, когда вы один раз собрали вручную и поняли, кого подменяете.

Контейнер, service locator, ручная склейка

Контейнер полезен, когда объектов десятки и склейка руками превращается в простыню. Цена: невидимые зависимости, циклические графы, старт приложения ради юнита. Договорённость: доменные сервисы не просят контейнер внутрь себя. Внутрь — роли. Контейнер живёт у края, рядом с HTTP. Если юнит не стартует без «поднять контекст» — вы тестируете фреймворк, не сценарий.

Service locator: объект сам ходит в глобальный «дай мне базу». Это прячет зависимость ещё сильнее, чем new. Тест должен настраивать глобальное состояние. На созвоне это слабый ответ. Локатор допустим в легаси на время, не как цель. Миграция: сначала конструктор на одном сервисе, потом вычищайте getInstance из середины.

Ручная склейка в composition root — норма для сервиса команды из пяти человек. Не стыдитесь. Стыдно, когда склейка размазана по двадцати конструкторам с new внутри. Один файл «как собираем прод» читается за минуту и экономит онбординг лучше, чем «у нас Spring, разберёшься».

Где DI вреден

  • Скрипт на вечер, миграция один раз, прототип к пятнице.
  • Слой абстракций на каждый чих в учебном CRUD без второй реализации.
  • Протаскивание десяти ролей в конструктор «на чистоту», хотя класс делает одну вещь с одной базой.
  • Поднимать Spring ради проверки, что 2+2 в калькуляторе заказа.
  • DI в резюме junior без репозитория, где шов видно.

Принцип окупается в коде, который живут и меняют. Для одноразового — мешает. На ревью аргумент: «тест перестанет ходить в сеть». Не: «так надо по Фаулеру». Статья Фаулера про injection полезна как история термина, не как чеклист вашего PR.

CV review

How does your resume look to a recruiter?

Upload a PDF or DOCX. In 1–2 minutes you get a score across 7 sections and fixes in order of impact.

AKAnna KovalevaFrontend · Middle
46

The best result is buried at the end

Worked on developing new features and fixing bugs. Took part in moving the cart to Next.js, after which conversion grew from 2.1% to 2.8%.

Rewrite

Moved the cart to Next.js with the team, lifting conversion from 2.1% to 2.8%.

Review my resumePDF or DOCX · 1–2 minutes

Тест как проверка, что шов не для галочки

После «внедрили DI» юнит всё ещё поднимает Postgres — вы переименовали. Настоящий шов: сценарий без сети за короткое время. Контракт с провайдером — отдельный тест на стенде, не каждый юнит. Если «юнит» стартует минуту и требует docker-compose — это интеграция, назовите её так. Путаница имён на созвоне выглядит как неумение резать зависимости, даже если контейнер настроен идеально.

Не гонитесь за процентом покрытия. Покройте шов, который жёг. Рекрутеру не нужен отчёт CI. Нужен рассказ: «этот тест не ходит наружу». Тот же критерий, что в SOLID-тексте, здесь применён к одной зависимости. Сломанный тест после смены SMTP при зелёной оплате — хороший признак, что шов живой.

Резюме и грейд

Не пишите DI рядом с Python как стек. Напишите, что подменили в тесте и какой шлюз вынесли. Junior: рабочий сценарий, хотя бы одна подмена. Middle: шов, который уже сэкономил выкладку. Senior: решаете, где контейнер не нужен. Грейд: ожидания уровня. Java без транзакции в пулях: резюме Java. Backend: резюме backend.

На интервью могут спросить «constructor vs setter». Ответ: явный конструктор, полный объект, проще тест. Не эссе про IoC container lifecycle, пока не спросили. Если спросят про FastAPI Depends или Spring @Autowired — переведите на роли: «вот что подменяю в тесте». Декоратор без подмены — снова магия.

Языки разные, шов один

В Python часто хватает протокола или утиной типизации и передачи объекта в функцию. Не обязательно класс с десятью абстрактными методами. В Java привычнее интерфейс и конструктор. В Nest и Spring контейнер громче — тем важнее не утащить его в домен. В Go конструктор с интерфейсом на два метода обычно честнее «wire на весь сервис ради учебника».

Не переносите привычку Spring в пет на Flask «потому что так взросло». Переносите шов: в тесте фейк, в проде клиент. Если язык позволяет передать функцию сохранения заказа — это тоже DI, только без слова. На созвоне скажите «передаю зависимость», не «у меня нет Spring, значит нет DI».

Частые вопросы

01Это не то же самое, что SOLID D?

D — принцип «зависеть от роли». DI — как роль попадает в объект. Читайте оба. Здесь практика шва, там пять букв и оверинжиниринг слоёв.

02Обязателен ли Spring / Nest?

Нет. Обязателен шов. Контейнер — когда склейка надоела, не в первый день пета. Вакансия «обязателен Spring» проверяет опыт экосистемы, не понимание injection. На созвоне всё равно могут попросить фейк без контекста — готовьте его.

03Можно ли new внутри фабрики?

Да, если фабрика у края и домен её не знает. new в середине сценария оплаты — снова жёсткая склейка. Фабрика, которую зовёт каждый метод сервиса, — тот же локатор в другом пальто.

04Сколько зависимостей в конструкторе нормально?

Если считаете больше пяти и не можете назвать, зачем каждая — класс делает слишком много. Это уже S из SOLID, не «мало DI». Длинный конструктор — сигнал резать класс, не прятать параметры в сеттеры.

05Нужен ли DI в скрипте аналитика?

Обычно нет. Нужен читаемый SQL и вывод. Не тащите контейнер в ноутбук. Если скрипт ходит в три API, достаточно передать клиенты аргументами функции, без жизненного цикла бинов.

06Как показать DI без коммерции?

Сервис с фейком в тесте и README, что подменяете. Курс «настроил Spring» без теста — слабо. Вход: резюме без опыта. Не рисуйте hexagonal ради портфолио: рекрутер ищет сценарий заказа, не порты.

Что сделать сейчас

Откройте один класс, который ходит в базу или HTTP. Выпишите, кого он создаёт сам. Вынесите одну роль в конструктор и напишите тест без сети. Если не выходит без контейнера — контейнер держит шов в заложниках, чините это, не добавляйте слово DI в LinkedIn сегодня вечером. Один шов за вечер сильнее курса про контейнеры за выходные.

Буквы и слои, если полезли руки рисовать круги: снова SOLID. Вакансии того же объёма: каталог, не «все senior architecture». Каркас файла: как составить резюме, проверка cv-review. Если после выноса роли тест всё ещё ходит в сеть — слово DI в LinkedIn не добавляйте: шов ещё бумажный.

Next step

Try this article's advice on your own resume

The review highlights the lines where recruiters lose interest and suggests what to write instead.

  • A score out of 100 across 7 sections
  • Ready-made rewrites for weak lines
  • How well you fit a specific vacancy
Review my resumePDF or DOCX · 1–2 minutes
Sample reviewFrontend · Middle
46

Was 46
Now 87 / 100

  • Summary3 → 9
  • Experience4 → 9
  • Skills5 → 9

On this page

  1. Боль: жёсткая склейка, не отсутствие фреймворка
  2. Конструктор, а не магия полей
  3. Пример 1. Заказы и почта
  4. Пример 2. Созвон «у нас Nest, значит умею DI»
  5. Контейнер, service locator, ручная склейка
  6. Где DI вреден
  7. Тест как проверка, что шов не для галочки
  8. Резюме и грейд
  9. Языки разные, шов один
  10. Частые вопросы
  11. Что сделать сейчас

Categories

  • All articles
  • Job Search
  • Resume & CV
  • Cover Letters & Applications
  • Interviews
  • Salary & Offers
  • Job Reviews & Roundups
  • Remote Work
  • Career
  • Career Growth
  • Market Trends
  • Onboarding
  • Tips

Related articles

  • Как готовиться к собеседованиям системно

    7d ago

  • Тайм-менеджмент для поиска работы при загруженности

    19d ago

  • Как не выгореть во время долгого поиска работы

    30d ago

  • Синдром самозванца у разработчиков: что с ним делать

    42d ago

  • Уведомления о вакансиях в Telegram и LinkedIn: как откликаться раньше

    54d ago

Looking for a job?

IT roles with remote and relocation options.

Browse jobs
AboutPublic OfferTerms of ServicePrivacy PolicySupport
AboutPublic OfferTerms of ServicePrivacy PolicySupport

By Region

  • Jobs in Europe
  • Jobs in USA
  • Jobs in Canada
  • Jobs in Russia

By Format

  • Remote Jobs
  • Relocation to USA
  • Hybrid Jobs
  • Office Jobs

By Experience Level

  • Junior Jobs
  • Middle Jobs
  • Senior Jobs