Ответ 1
Когда я вызываю injectionBaseActivity (это), он "сообщает" кинжалу, что все аннотации @Inject являются зависимостями моего класса, а затем он ищет мой проект для аннотированных конструкторов @Inject, которые соответствуют этому типу?
Совершенно верно. Но это не делается, когда вы вызываете injectBaseActivity
, но все это происходит во время компиляции. Это один из способов обработки обработки аннотаций (другой использует отражение во время выполнения).
Когда вы создаете свой проект, вы можете включить обработчик кинопленки-аннотации, который вы включаете (как зависимость) в свой файл build.gradle, со списком всех ваших полей, классов и т.д., аннотированных аннотацией @Inject
, и строит граф зависимости с ним. Затем он решает график, генерируя исходный код, который предоставляет все зависимости для элементов на графике.
injectBaseActivity
просто выполняет код, который был сгенерирован ранее, и назначает все зависимости вашему объекту. Это правильный исходный код, который вы можете читать и отлаживать.
Причина, по которой это шаг компиляции, просто put — - это производительность и валидация. (например, если у вас есть некоторый цикл зависимостей, вы получаете ошибку компиляции)
как кинжал знает, что мои AuthControllers являются зависимыми для BaseActivity?
@Inject
AuthController authController;
Аннотируя поле @Inject
, кинжал знает, что вы хотите AuthController
. Все идет нормально. Теперь кинжал будет искать некоторые средства для обеспечения контроллера, поиска его в компоненте, зависимостях компонентов и модулях компонентов. Он также посмотрит, может ли класс быть поставлен сам по себе, потому что он знает о его конструкторе.
Как кинжал знает о конструкторе объектов, если вы не включаете его в какой-либо модуль?
@Inject
public AuthController(Context context) { /**/ }
Аннотируя конструктор с инъекцией, вы также сказали кинжалу, что есть класс под названием AuthController
, и вам нужен контекст для его создания. Это в основном то же самое, что добавлять его в ваш модуль.
Метод @Provides
должен использоваться, если у вас нет исходного кода, чтобы просто добавить аннотацию @Inject
к конструктору или если объект нуждается в дальнейшей инициализации. Или в вашем случае...
[...] файлы модуля могут использоваться как "документация" моего дерева зависимостей [...]
Да, конечно, вы могли бы это сделать. Но по мере роста вашего проекта вам придется поддерживать много ненужного кода, так как это можно было бы сделать с помощью простой аннотации к конструктору.
Есть ли какие-либо рекомендации по использованию @Inject-аннотаций в конструкторах или при добавлении метода @Provides в файлы модулей?
Если вы хотите предоставить разные версии для другого контекста (например, для реализации интерфейса двумя разными способами), также существует аннотация @Binds
, которая сообщает кинжалу, какой класс вы хотите предоставить как реализацию.
Кроме того, я считаю, что вы всегда должны использовать инъекцию конструктора, когда это возможно. Если что-то изменится, вам не нужно прикасаться к каким-либо другим частям вашего кода, и это всего лишь код, который вы пишете, и, следовательно, меньше мест, где вы могли бы включить ошибку.
Также Dagger может и очень много оптимизирует, зная больше, и если вы реализуете ненужный код, ему придется работать с накладными расходами, которые вы ввели
Конечно, в конечном итоге все зависит от того, что вы считаете лучшим. В конце концов, это вы должны работать с вашим кодом;)