Чем отличаются друг от друга DI через конструктор, поле и метод?
1. В моем понимании DI через конструктор заключается в том, что мы передаем классу зависимости которые критически важны для его работы и без них он просто не может работать. Например класс Car имеет Engine. Его мы передаем в конструктор. Если мы не передадим реализацию Engine, то класс просто не будет работать.
2. DI через поле это внедрение зависимостей с "низким приоритетом" то есть например Retrofit может работать без логгера. Но если мы хотим, мы можем указать логгер для http клиента.
3. DI через метод - это когда мы передаем зависимость конкретному методу, которая используется только в этом методе.
Можете пожалуйста дополнить или раскритиковать то что я написал?
Дело не в критичности и приоритетах, дело в плюсах и минусах каждого подхода в конкретных ситуациях. Внедрение через конструктор удобно, позволяет инициализировать финальные поля и гарантирует правильное состояние объекта, но из-за него может распухать список аргументов конструктора. У внедрения в поле сплошные минусы, но зато его можно использовать с кодогенерацией. Внедрение через метод - средний вариант, в меру сочетающий достоинства и недостатки.