RecipePresenter имеет конструктор, аннотированный @Inject
, что позволяет его предоставлять.Аннотация @Inject
в поле recipePresenter
в RecipeActivity не помогает, только конструктор, аннотированный @Inject
.
class RecipePresenter @Inject constructor(
private val useCase: RecipeUseCase,
private val res: StringRetriever) :
RecipeUseCase.Callback {
Из руководства пользователя Dagger:
Используйте @Inject
, чтобы аннотировать конструктор, который Dagger должен использовать для создания экземпляров класса.Когда запрашивается новый экземпляр, Dagger получит требуемые значения параметров и вызовет этот конструктор.
Если класс с конструктором, аннотированным @Inject
, также имеет определенный scope тогда привязка будет влиять только на компоненты с той же аннотацией области: например, класс @ActivityScope
не будет доступен из компонента @Singleton
.Если для класса не определена область действия, то привязка может появиться в любом и во всех компонентах, где это необходимо, и это нормально: реализация всегда одна и та же, определяемая самим конструктором.
@Inject
имеет различные значения в зависимости от того, что он аннотирует:
- Когда вы аннотируете поле с помощью
@Inject
, это означает, что система DI должна установить это поле на основе значений изсистема DI , когда вводит этот объект. - Когда вы аннотируете метод с помощью
@Inject
, это указывает, что система DI должна вызывать этот метод с параметрами, основанными на значениях из системы DI когда вводит этот объект. - Когда вы аннотируете конструктор с помощью
@Inject
, это указывает, что системе DI разрешено вызывать этот конструктор для создания этого объекта (который инициирует введение поля и метода выше).В этом смысле он действует как встроенный провайдер.
В частности, в Dagger методы @Provides
имеют приоритет над конструкторами @Inject
(если они оба существуют для одного и того же класса), и в отличие отв спецификации JSR-330 Dagger требуется аннотированный конструктор @Inject
, даже если другие конструкторы отсутствуют.Из Руководства пользователя Dagger:
Если в вашем классе есть поля, аннотированные @Inject
, но нет конструктора, аннотированного * 1054, Dagger вставит эти поля по запросу, но не будет создавать новые экземпляры.Добавьте конструктор без аргументов с аннотацией @Inject
, чтобы указать, что Dagger может также создавать экземпляры.
Классы, в которых отсутствуют аннотации @Inject
, не могут быть созданы Dagger.
Наконец, чтобы ответить на ваш вопрос о том, почему действия и фрагменты нужно вводить самим: Android разрешено рефлексивно создавать объекты Activity / Fragment / View без помощи или участия Кинжала. Это означает, что поле ничего не вызываети внедрение метода, описанное выше, до тех пор, пока вы не вызовете метод внедрения членов в компоненте , который инструктирует Dagger заполнить эти поля и вызвать эти методы.Следовательно, вы никогда не должны видеть аннотированный конструктор @Inject
в подклассах Application, Activity, Service, Fragment, View, ContentProvider и BroadcastReceiver в Android: Android будет игнорировать аннотацию @Inject
, так что вы могли бы также взять под контроль внедрениесамостоятельно, вручную или через dagger.android .