Что такое Dependency Injection (DI)
Что проверяют
Отличаете ли вы принцип от контейнера. Внедрение зависимостей это про архитектуру, контейнер Symfony или Laravel это инструмент, и подмена одного другим сразу слышна.
Как отвечать
Dependency Injection это когда объект не создаёт свои зависимости сам, а получает их снаружи. Обычно через конструктор:
final class OrderService
{
public function __construct(
private readonly PaymentGateway $payments,
private readonly LoggerInterface $log,
) {}
}Что это даёт: класс зависит от интерфейса, а не от конкретной реализации. В тесте вместо платёжного шлюза подставляется заглушка, в проде реализация меняется одной строкой в конфигурации контейнера, а по конструктору сразу видно, от чего класс зависит.
Способы внедрения: конструктор (по умолчанию, зависимость обязательна), сеттер (для необязательных), метод (когда нужна ровно в одном вызове).
В Symfony контейнер собирает граф по автовайрингу и типам аргументов, в Laravel через сервис-контейнер и байндинги интерфейсов на реализации. И там и там есть общие для процесса сервисы и создаваемые на запрос: их время жизни и есть то, что чаще всего ломают.
Где спотыкаются
Считают, что DI это библиотека. Передать зависимость руками в конструктор это уже DI, контейнер лишь избавляет от ручной сборки графа.
Тянут контейнер внутрь класса и просят у него зависимость в методе. Это Service Locator, и по сигнатуре больше не видно, что классу нужно.
Внедряют конкретный класс вместо интерфейса, после чего подменить его в тесте нечем.
Приводят конструктор с десятью зависимостями как пример гибкости. Это признак того, что у класса больше одной ответственности.