Как стать автором
Обновить

Комментарии 30

Отличная статья. Спасибо Евгению.
Сэкономила и ещё сэкономит кучу времени в поисках нужной информации и её осмысления.

Спасибо за хорошую статью. Подобного материала действительно мало, и собирать его приходится с многих источников.
У меня вопрос по тестированию. Кроме подхода Артема Зиннатулина, есть еще библиотека от Фаббио Коллини — DaggerMock. Приходилось ли Вам смотреть ее раньше? И если да, то чем не подошла?

Спасибо за новую информацию. Честно говоря, не работал с ней. Но обязательно посмотрю)
Спасибо за статью.
Возник вопрос с Binds. Может ли сабкомпонент иметь абстрактный модуль в качестве зависимости? Если да, то как создать такой модуль?
Спасибо, поправил.
FirstModule, а не HelperModule. Абстрактный модуль подключается точно также, как и обычный. Никаких отличий.
Я как понял абстрактный модуль нельзя использовать в plus (ибо нужна реализация). Зато заработало если включить абс. модуль в неабстрактный модуль (includes в аннотации).
А, понял Вас.
Попробую разные варианты и добавлю к статье.
Спасибо большое!
А в каких случаях оправдана такая архитектура? Просто с первого взгляда это выглядит все страшно и непонятно ) Большинству приложений не требуется столько провайдеров и модулей. Все никак руки не дойдут сесть за изучение этого инструмента) Использую только для инъекции нескольких отдельных модулей. Но дальше этого уже слабо разбираюсь) Может есть какая отдаленная информация по этой тематике? Не в контексте андроида.
В любом более-менее серьезном приложении =)
Вы и заметить не успеете, как обрастете классами и разными зависимостями.
Для домашнего проекта, конечно же, это все можно опустить.
Скажите, а будет ли Dagger 2 работать вне Android? Я в одном проекте (не андроид) использую Dagger 1.
Смущают вызовы MyApplication.getInstance().getFirstComponent().inject(this) — не ясно, куда вставлять эти вызовы в обычном приложении.
По поводу «вне Android» не могу сказать, так как не знаю.
Вызовы эти вставлять в зависимости от вашей логики. Обычно в onCreate() Активити или фрагмента.

Несмотря на то, что Даггер второй писался для андроида, явно андроидовские зависимости Даггер нигде не тянет. Вся его андроидо-ориентированость — это неиспользование рефлексии и меньшее потребление ресурсов, правда за счет большего оверхеда в написании кода. Так что теоретически должен работать и вне его.

Будет работать, юзаю для бекенд приложений.


MyApplication.getInstance().getFirstComponent().inject(this) — не ясно, куда вставлять эти вызовы в обычном приложении.

Зависит от того, как построено ваше приложение, если на каком-то фреймворке типа Spring/Jersey — там так же есть объекты приложения, можно завязаться на них, в простейшем случае с public static void main() вы можете просто таскать component сквозь все функции и обойтись вообще без классов!


Google изначально делали Dagger2 для своих бекендов.

Экономия и минус лишние вызовы. Собственно у нас выигрыш по производительности. Также пишут, что вызов статического метода на 15-20% быстрее вызова аналогичного нестатического метода. Если я ошибаюсь, iamironz поправит меня. Уж он то точно знает, а если нужно, и замерит.


Данный тезис правдив скорее до Android API 19. На данный момент invokestatic почти ничем не отличается от invokevirtual т.к. в ART он девиртуализируется достаточно эффективно.
Вопрос скорее для вводного понимания, никак не могу вкурить:

Вот, скажем, провайдим мы в AppModule сингельтон ApiClient, который далее много где планируется использовать.
И в итоге чтобы его заюзать нужно везде дергать что-то вроде?:
App.get(context).getComponent().inject() или App.get(context).getComponent().getApiClient()
т.е везде тянется зависимость от Application
чем это отличается от того, чтобы просто дергать App.get(context).getApiСlient() без использование Dagger?
Т.е весь код в итоге все равно будет обвязан App.getComponent, это смущает

А читали первые две статьи?
да, вопрос как бы к первой вводной статье.
Возмодно я что пропустил, но пока не понял можно ли избавиться от привязки к Application везде где нужно сделать inject
Ну, конечно же. В сабкомпонентах все зависимости от родительского компонента будут доступны автоматом, и не придется тянуть AppComponent, будете только соответствующим сабкомпонентом работать.
Может эта статья прояснит больше — https://habrahabr.ru/company/tcsbank/blog/312196/
То? Или вы несколько про другое?
Такой вопрос, можно ли в даггере каким-то образом реализовать следующее
Есть ParentClass1 и ParentClass2 которые реализуют интерфейс MyCallback
Есть ChildClass
конструктор класса ChildClass выглядит вот так
public ChildClass(MyCallback callback) {...}
т.е. Child имеет связь с Parent через интерфейс

Я бы хотел в классе ParentClass1 и ParentClass2 указать
Inject
ChildClass childClass;

Как-то запутанно выходит, не думаете? =)
Вроде все просто. На самом деле задача звучит так.
Нам нужно к презентеру подключить зависимый презентер, а этот зависимый презентер хочет некий интерфейс от родителя.
Можно конечно поключать интерфейс позже к зависимому презентеру, но вот интересно умеет ли даггер что-то подобное.
Тут уже больше вопрос по архитектуре.
Презентер и зависимый презентер. Почему так? Почему вы решили так разделить? Вообще зачем презентерам знать друг о друге? Их можно связать через локальный «EventBus».
Чего такого дают модули dagger, чего нет в настоящиx модулях (android library), которые поддерживаются на уровне gradle (с зависимостями, своими ресурсами, мёржем манифеста и flavours)?
dagger упрощает вам задачу реализации DI у себя в приложении. Иначе вам придется вручную создавать и прокидывать зависимости. Это значительное уменьшение boilerplate кода. Вот, что самое главное.
Конечно, никто не запрещает вам подменять код через flavors. Но dagger — это не только лишь возможность подмены кода.
Иначе вам придется вручную создавать и прокидывать зависимости.

Поясните пожалуйста.

Очевидно, что вот это тоже пишется не автоматически:
@Inject
@Named("SingleThread")
Executor singleExecutor;

/*далее в onCreate*/

Executor singleExecutor = singleExecutorProvider.get();


При этом lazy load вообще выглядит громоздким. Я смутно могу себе представить, зачем нам понадобился ThreadPoolExecutor в activity, но допустим. Без даггера мы могли бы например написать просто:
Executor singleExecutor = ThreadPoolFactory.getSigleExecutor();//одна строчка!!!
Это было в качестве примера.
А вы читали первые две статьи? Там я в принципе раскрываю, зачем нужен Даггер и как его готовить.
Читал.
Готовить его для начинающего сложно. А польза сомнительна. В том числе и с точки зрения поддержки кода и понимания логики работы приложения в целом.

RxJava ты могуч, ты гоняешь стаи туч… Скажите на ваш взгляд если нужно что то вроде Supplier только для поздней инициализации, но не хочется тянуть по тем же причинам Guava и если сделать это как:


Observable<String> lazyString = Observable.just("Just do it");
// Usage
lazyString.toBlocking().first();

Насколько нарушается кошерность и можно ли это сделать по другому, без ретро ламбда?

JFYI Observable.just("Just do it") не lazy, вы вычисляете аргумент во время вызова just, а не во время подписки. Observable.fromCallable — lazy, defer() тоже и тп.


В вашем случае, что нибудь вроде Callable<String> подойдет, если не нужно кеширование результата. Если нужно кеширование, то это классик строк на 10, который будет вычислять значение если его еще нет в кеше, и отдавать из кеша если уже есть. Если вы используете Kotlin, в его stdlib есть lazy.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории