Основы DI и Dagger, как работает, настройка в проекте
Ғылым және технология
Из урока вы узнаете про Dependency Injection, как работает Dagger, подключите его в проект
🔗 Каналы "Android Broadcast" taplink.cc/android_broadcast
🔗 Поддержать проект taplink.cc/android_broadcast/...
🔗 Документация по Dagger dagger.dev/dev-guide/
📺 Курс по Dagger 2 abdev.by/wP1
🔗 Код из примера abdev.by/6AT
Видео сделано при поддержке Лаборатории Касперского
#AndroidBroadcast #DaggerКурс #Dagger2 #DI #DependncyInjection #Hilt #DaggerHilt #КириллРозов #РозовКирилл
0:00 Вступление
1:02 Теория DI
1:57 Dagger 2
2:30 Как работает Dagger 2
3:43 Подключаем Dagger 2 в проект
5:14 Простейший пример использования Dagger
10:55 Как долго живёт компонент?
11:27 Использование Dagger в Android приложении
16:41 Заключение
Пікірлер: 208
Информативно, никакой воды, полезные практики на примере, да еще и бесплатно. Кирилл, в раю для тебя выделено отдельное место :)
@AndroidBroadcast
3 жыл бұрын
Спасибо 😊
@_o6571
2 жыл бұрын
это да...
Очень доступно! Качество на уровне! Благодарю)
Просто вышка. То что надо и все по делу👍
Это лучшее что я видел по этой теме!!! Спасибо!
Ждём продолжения!! Спасибо!
Отличное видео получилось, жду продолжения! Спасибо👍
Отличнейший формат! Кратко и всё по делу. Спасибо за труд, Кирилл!
Спасибо за урок, все понятно и без лишней информации
Спасибо, ждём продолжения!!!
Спасибо за видео. Жду следующего)
Оооочень интересный урок. Спасибо большое, Кирилл. Появилось желание смотреть побольше твоего live coding content, потому что вижу очень много best practice for development. Thanks a lot =)
Отлично! Определено надо делать продолжение)
Отличный материал, спасибо!
Спасибо тебе Кирилл, это очень полезный курс
Спасибо за видео! Ждем продолжение!
Отличное начало!
Спасибо за работу, было интересно 🤩😍
Урок отличный! Спасибо!
Кирилл, спасибо! Как всегда топчик!
Очень крутое и понятное объяснение, большое спасибо!
Отлично, на одном дыхании смотрится. Спасибо за качественный контентк
Лайк и коммент желательно сотворить всем!))
Идеальное объяснение, спасибо!
Спасибо за курс!
Большое спасибо, Кирилл.
Интересно. Спасибо за лекцию
Лайк не глядя , спасибо огромное !
Большое спасибо за урок!!!
Супер. спасибо за материал)
Молодец, Кирилл! Спасибо, Кирилл!
Заранее лайк!!! Спасибо Вам!!!
Спасибо Кирилл!
Все четко, понятно просто супер!!!
Супер, спасибо!
Крутой материал, коротко и понятно)
Nice ) Просто и доступно!
Каааеф, очень доходчиво
Шикарно, спасибо
Практическая часть супер наглядная 👍
Круто, спасибо
лайк сразу)
Спасибо, все понятно и интересно!
@AndroidBroadcast
3 жыл бұрын
Спасибо. Вы даже не представляете как я рад этому
Круто! Спасибо!
Отлично 🖖
Кирилл, вот прям красава. Хороший формат! Для начинающих прям огонь, всё в принципе доступно разложил.!
@AndroidBroadcast
3 жыл бұрын
Спасибо. Надеюсь следующий выпуск зайдёт не меньше! Там уже погружение в фичи
Лайк, спасибо!
Лайк не глядя просто! Жаль, что нельзя еще один лайк после просмотра. Но вот комент напишу еще раз более подробно о своих впечатлениях!
@AndroidBroadcast
3 жыл бұрын
Супер! Жду ваш отзыв здорово поможет улучшать этот и будущие курсы
Спасибо!
Если не трудно, было бы гораздо удобнее, если бы когда вы какие-то новые вещи рассказываете, выводить какую-то схему, где вы ее объясняете. На слух, иногда сложно составить всю картину происходящего. В данном ролике вроде бы все не так сложно, но думаю, было бы полезно.
@AndroidBroadcast
3 жыл бұрын
В будущих роликах практически теории и не будет, так что таких проблем не возникнет
Ништяк!
спасибо большое👍👍
Спасибо большое
Ждём следующую часть
@AndroidBroadcast
2 жыл бұрын
Уже вышел весь курс!
Большое спасибо за курс! Как раз всё никак не разберусь, как правильно работать с даггером в многомодульном проекте.
@AndroidBroadcast
3 жыл бұрын
Я вас как раз подготовлю к тому, чтобы это сделать лучше и пока как. Ребята из Лаборатории Касперского также поделятся своим опытом
Спасибо
кааайф, давай ещё)
@AndroidBroadcast
3 жыл бұрын
Второй урок уже на канале
Спасибо, хотелось бы больше теории
@AndroidBroadcast
3 жыл бұрын
Курс не хочется делать теоретическим, но обязательно пишите что хотите узнать лучше (только отдельным комментарием под видео, чтобы за него могли поголосовать люди)
@Tswet
3 жыл бұрын
@@AndroidBroadcast да просто бездумное копирование вашего кода тоже пользы много не принесет :( а с теорией может с умом бы копировали :) (хотя нет)
super
ну круто же
Спасибо за труд. Наверное, это лучшее видео среди ру-сегмента ютуба. Множество авторов статей по даггеру используют зависимость dagger-android, следует ли вообще пользоваться ею?
@AndroidBroadcast
3 жыл бұрын
dagger-android был раньше, но сейчас он уже deprecated и рекомендуется использовать Dagger Hilt dagger.dev/hilt/ и Jetpack Hilt d.android.com/jetpack/androidx/releases/hilt
Поменяйте, пожалуйста, звук переключения между темами в начале. Он какой-то резкий и громкий. По ушам сильно бьёт.
@AndroidBroadcast
3 жыл бұрын
Окей, обратим внимание
@mrtwon8638
3 жыл бұрын
@@AndroidBroadcast прошлое интро топ было, особенно музыка 👍
Спасибо, доходчиво и красиво изложено. В своё время отказался от Dagger в пользу Kodein, потому что Dagger показался неуклюжим, громоздким и overengeneered.
@AndroidBroadcast
3 жыл бұрын
Какое впечатление складывается сейчас?
@Feivur
3 жыл бұрын
@@AndroidBroadcast Честно говоря, желания использовать не возникает. Выглядит страшно. Возникает недоумение, почему такой монстр популярнее других простых и компактных фреймворков. Но знать его в лицо надо, и твоё изложение очень помогает, жду следующие серии!
Попробуй продублировать инфу по поводу второго видоса в описании к видео, либо в начале видоса вставить ее текстом, например. Многие смотрят не до конца, а лишь ту часть, которая им полезна и сразу вырубают видос без лайка и не понимают потом где продолжение курса)
@AndroidBroadcast
3 жыл бұрын
Есть плейлист целый и выходят видосы. Тут я уже ничего не сделаю, если людям неинтересно
Залайкайте це відео )
Хотелось бы увидеть конкретные примеры зачем нужен Dagger. Какие проблемы имеет код, в котором не используется DI? Может быть примеры "реальных" useCase'ов? Я предполагаю что Dagger облегчает написание тестов. Хотелось бы увидеть насколько легче писать тесты с Dagger'ом и без него?
@AndroidBroadcast
3 жыл бұрын
Таких убеждений я проводить не буду. В этом видео я объяснил зачем он нужен - ослабление связи между типами и масштабирование кодовой базы
@AndroidBroadcast
3 жыл бұрын
Вот тут всё можно почитать, там совсем просто говориться о Dagger в тестах dagger.dev/dev-guide/testing.html
Спасибо за видео, очень познавательно. Cреди примеров я находил очень много тех, которые связаны именно с классами моделей. Но неоднократно слышал, что можно при работе с сетью, передавать с помощью DI репозиторий во ViewModel и т.д. Очень хотелось бы увидеть пример того, как это делать правильно, а также применение DI не только в работе с данными, если это допустимо. Спасибо!
@AndroidBroadcast
3 жыл бұрын
Это первая лекция курса и я не хотел нырять с головой в реальный код, дальше будет погружение в Android код по современным стандартам Google и применение Dagger там
@mitiaygorodov4939
3 жыл бұрын
@@AndroidBroadcast Спасибо! Очень полезный курс, всё очень понятно.
Спасибо, Надеюсь в будет объяснения как инжектить в классы в которых нет Context
@AndroidBroadcast
3 жыл бұрын
Так есть пример Repostiory. Context - такая же зависимость как и все остальные, разницы нет
Спасибо за очередной крутой материал! А будет про коин?
@AndroidBroadcast
3 жыл бұрын
Нет, про Koin отдельного ничего делать не собираюсь, так как не интересно. Разве что "Почему ч отказался от Koin в пользу Dagger"
@Chekist2008
3 жыл бұрын
@@AndroidBroadcast ну понятное дело что ран-тайм и все такое, но он же ведь однозначно проще для понимания чем даггер.
@user-qv7po6wv6o
3 жыл бұрын
@@AndroidBroadcast помнится, первое видео на этом канале, которое я увидел, называлось "Почему Koin")
Было бы хорошо если бы вы опираясь на свой опыт сделали тестовый проект несложный с применениям разных инструментов по типу того же Dagger 2/MVVM/ и т.д =)
@AndroidBroadcast
3 жыл бұрын
Да, это будет ближе к концу курса
Хотелось бы подробное видео про lateinit. До сих пор не понимаю, что с ним не так. По-хорошему, jb должны были хорошо над ним поработать (как с object-классами), чтобы все было ок с ним.
@AndroidBroadcast
3 жыл бұрын
Отдельного видео он очно не заслуживает, может если только в группе советов про Kotlin
Здравствуйте, я правильно понимаю, что это нужно для того чтобы не хранить applicationContext в глобальной переменной? И управлять порядком сборки MainApp? Или я не так понял, в чем смысл DI. Можете, пожалуйста, объяснить, очень хочу использовать в своем проекте.
Благодарю за видео, Кирилл! Каким образом AppComponent распознает метод где указан класс куда надо будет предоставить зависимость? Я так понимаю там под капотом проверка что если задается функция с любым названием, но с входным параметром (fun inject(activity: MainActivity)) , значит эта функция как раз и отвечает за требование предоставление зависимости, верно?
@AndroidBroadcast
2 жыл бұрын
Процессор аннотаций находит все классы, которые помечены аннотациями Dagger и на этапе процессинга всё связывает
@MarsIanin06
2 жыл бұрын
@@AndroidBroadcast Понял, спасибо!
насчёт inject -ирования активности не очень понял, обязательно её инжектировать в AppComponent? То есть если мы хотим заинжектить в любой класс не помеченный интерфейсом @Component то должны сам класс заинжектировать в AppComponent?
@AndroidBroadcast
2 жыл бұрын
В Componet и Subcomponent добавляются методы в которые можно будет выполнить inject зависимостей по вызову этого метода из сгенерированного компонента. Лучше выполнять inject через конструктор, тогда такие методы в Componet не понадобятся, но не у всех компонентов можно поменять конструктор. Например, стандартный компоненты Android (Activity, Service) требуют наличия конструктора по умолчанию и создаются его вызовом, а позже в onCreate() можно сделать inject зависимостей
Можно ли показывать примеры сразу схожие на реальные, т.е. вот в этой папке у нас компонент, тут в отдельных модули. Вот где в итоге должен быть Context.appComponent я не особо понимаю, а в остальном все доступно, спасибо.
@AndroidBroadcast
3 жыл бұрын
Где вы поместите это расширение - неважно. Можно и без него обойтись, но оно продемонстрировано для удобства. Выносить его в отдельный файл было бы только расфокусом во время демонстрации кода
📢Кто только начал учить Dagger 2 обратите внимание на версию Котлина в проекте. Почему? Потому что проекты на новых версиях Котлина работают с Даггером некорректно (Заработало с версией 1.4.32)
@AndroidBroadcast
2 жыл бұрын
С какой именно версией?
@agentr227
2 жыл бұрын
@@AndroidBroadcast с 1.6, которая стояла у меня, но пишут, что такие проблемы с 1.5+ версиями котлин. Проект просто крашился при билде после того, как пытался заинджектить поле в Activity. (У друга аналогично всё было, проект нормально стал запускаться после смены версии кота на 1.4.32)
Возникли некоторые вопросы : почему вы расширили именно Сontext? Что если у нас будет несколько компонентов типо ActivityComponent, FragmentComponent расширить Context опять ? Нельзя ли создавать какой нибудь глобальный типизированный функция и в зависимости от типа вернуть нужные компонент ?
@AndroidBroadcast
Жыл бұрын
Указывайте таймкод, я не понимаю про что вы говорите
@voicetv9048
Жыл бұрын
@@AndroidBroadcast 12:40 вы расширили Context при использовании даггер в андроид , про него и был вопрос !
@AndroidBroadcast
Жыл бұрын
Это просто вспомогательная функции, вы можете написать свою какую угодно.
Большое спасибо. У меня вопрос, чутка не понял А зачем проверять тип контекста при получении appComponent`a ? В коде when (this) { is MainApp -> appComponent else -> this.applicationContext.appComponent } Зачем проверять, если можно сразу вызвать this.applicationContext.appComponent ? Какое здесь отличие ? В любом же случае достанем тот же самый appComponent
@AndroidBroadcast
2 жыл бұрын
applicationContext также вернет тип Context. Свойство appComponent существует только в типе MainApp, соответственно нам нужно получить переменную такого типа. is MainApp в when позволяет нам убедиться что текущий Context - это MainApp и автоматически выполняет cast
На одном из проектов использовал by lazy для получения компонента. Что думаете на этот счет?
@AndroidBroadcast
3 жыл бұрын
Делегат lazy? Это случаем не Koin?
@user-vd8wv3vo8t
3 жыл бұрын
@@AndroidBroadcast нет не Koin. Например _val appComponent: AppComponent by lazy { DaggerAppComponent.create() }_. Тем самым ухожу от использования lateinit.
@AndroidBroadcast
3 жыл бұрын
Я подумал ты про inject, а не создание AppComponent
Посидел пару лет на коине, теперь хочу вернуться в даггер. Правда через хилт, но не суть.
@AndroidBroadcast
3 жыл бұрын
Hilt тоже будет в курсе
Все огонь, но то ли Dagger поменялся, то ли я по невнимательности что-то пропустил, но у меня в упор не создается класс DaggerAppComponent
@AndroidBroadcast
Жыл бұрын
Подключил kapt или apt и настроил с Dagger для генерации кода?
@oleg12395
Жыл бұрын
@@AndroidBroadcast да, все огонь. Спасибо, с непривычки бывают застревания в таких простых вещах
Кирилл привет, у меня не появляется DaggerAppComponent и как скомпилировать граф зависимости?
@AndroidBroadcast
2 жыл бұрын
Причины может быть 2: не проставлены аннотации или не подключен процессор аннотаций (зависимости в Gradle через kapt или apt). Вопросы лучше задавать тут Android Broadcast t.me/android_broadcast_talks
@alexeyflyagin
Жыл бұрын
Подскажите, была ли решена проблема у вас? Я уже и проверил все аннотации по тысячу раз и пробовал с kapt и c apt и пытался и так и этак, а все равно не генерируется ничего. Если решили проблему, не подскажете ли как мне ее решить?
@AndroidBroadcast
Жыл бұрын
Пишите в t.me/android_broadcast_talks
Коллеги, вот у нас на фирме во всех проектах подключен и используется Dagger, но я за 4 года так и не понял зачем, какова его ценность в реальном мире?
@AndroidBroadcast
7 ай бұрын
Тогда вам стоит лучше почитать про архитектуру софта и зачем нужен DI, либо пользоваться другим решением
Целесообразно ли использовать dagger support?
@AndroidBroadcast
2 жыл бұрын
Я так понял речь про Dagger Android. Его уже не рекомендуют использовать, а брать Hilt
Если я создам объект в Application, а потом буду обращаться к нему из разных частей кода, например, из фрагментов - это же и есть "создать в одном месте", а обращаться отовсюду? Насколько я понимаю, даггер так и работает под капотом? Application - это же, по сути, единая точка входа в андроид приложение, то что живет на протяжении всего времени жизни запущенного приложения и точно существует в любой момент времени.
@AndroidBroadcast
3 жыл бұрын
Не совсем так, это уже больше Service Locator. Также неправильно перегружать логикой Application класс и хранить всё на протяжении его жизни. То что вы описали рабочий подход, но DI имеет больше возможностей и независимости. Рекомендую почитать стать на тему сравнения
💰 Поддержать проект на Boosty bit.ly/3sratqQ или Patreon patreon.com/android_broadcast 🔗 Telegram канал "Android Broadcast" ttttt.me/android_broadcast 📺 Курс по Dagger 2 clck.ru/ViWKV
всё делал как в уроке, но не находит DaggerAppComponent
@inquisitor4894
11 ай бұрын
Ответ прост: Нужно собрать проект, после проверить, должен появиться.
Не не не первую зависимость я уже получил, больше не надо
Почему может не генерироваться DaggerAppComponent?
@AndroidBroadcast
Жыл бұрын
- Не настроил процессор аннотаций (kapt для Kotlin) - Нужно чтобы был интерфейс AppComponent с аннотацией @Component - Скомпилировать проект (возможно лучше начисто)
@user-kg7mp4jh6k
Жыл бұрын
добавил id("kotlin-android"), id("kotlin-kapt"), при билде дает A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction, stacktrace ничего внятного не говорит
@AndroidBroadcast
Жыл бұрын
Посмотрите раздел зависимостей в Gradle. Это банальный вопрос - вы подключили процессор аннотаций, но нужнл с помощью него подключить dagqer compiler. Ну странице документации Dagger есть все это и я показывал в примере
Как работает @Inject? Через рефлексию?
@AndroidBroadcast
3 жыл бұрын
Нет. Суть Dagger не использовать рефлексию во время работы приложений и генерировать весь код заранее.
А как строить модуль если объект содержит примитивные типы или стринг? Или как я понял дагер вообще не нужен для этого т.к это не его компетенция т.к на контроллере у меня прога просто не компилировалась.
@AndroidBroadcast
11 ай бұрын
С примитивными типами строить не получится, надо через типы-обертки примитивов или свои делать + лучше начать сразу использовать квалификаторы. На моем опыте все какие-то параметры оборачивались в один большой объекте конфига
в чем разница между lateinit var и private var _appComponent: AppComponent? = null internal val appComponent: AppComponent get() = checkNotNull(_appComponent) { "AppComponent isn't initialized" } в обоих случаях если не будет инициализации то будет ошибка только текст разный
@user-yd4si7yd3b
3 жыл бұрын
просто не могу понять насколько сильная была боль, которая связана с lateinit, что каждый раз вы говорите о том, что лучше не использовать?) это же по факту тот же nullcheck.
@user-qt2gu2pm2m
3 жыл бұрын
При использовании lateinit требуется проверять с помощью метода isInitialized, что объект был проиницилизирован, что может сказаться на производительности Плюс не стоит забывать про UninitializedPropertyAccessException
@AndroidBroadcast
3 жыл бұрын
По сути поведение конечное одинаковое, но мне не нравится что lateinit выкидывает непонятное исключение и порой разработчики им начинают увлекаться, даже там где это не надо. Моё правило - lateinit только где есть аннотация Inject (даже в Detekt есть такое правило)
@AndroidBroadcast
3 жыл бұрын
Если вы один, то контролировать это просто. Но вот на уровне команды правила нужны. Особенно я помню как наелся на нескольких проектах с крешами в проде из-за неоправданного использования lateinit, а понять по stack trace было невозможну исходную причину
@user-yd4si7yd3b
3 жыл бұрын
@@user-qt2gu2pm2m проверять нужно, только если вы не уверены в том что переменная проинициализирована.
А зачем когда есть уже инджект нам нужна проперти computer в интерфейсе AppComponent это избыточно, можно удалить.
@AndroidBroadcast
3 жыл бұрын
Это было лишь для примера
@TheKostya29
3 жыл бұрын
@@AndroidBroadcast я так и понял, но если на место новичка стать, кто-то может начать это делать у себя по аналогии
лучше ведь binds использовать вместо provides
@AndroidBroadcast
3 жыл бұрын
Если есть возможность, то да. Подробнее об этом будет в следующем выпуске
Я только начинаю знакомится с миром андройда, и у меня тут возникает вопрос: если activity, и иные примитивы андройда не предполагают чтобы в них что-то внедряли - почему не использовать подход service locator, тем более dagger как понимаю даёт возможность это делать через тот самый create или билдер...
@AndroidBroadcast
2 жыл бұрын
Activity - это лишь точка входа и она не подстраивалась под какие-то либы или фреймворки. Много компонентов требуют наличие конструктора по умолчанию (без параметров)
@user-hr2dk6jy1k
2 жыл бұрын
@@AndroidBroadcast пока я склоняюсь к тому, что пытаются впихнуть di в сущность которая своим интерфейсом показывает что все зависимости можно добавлять только через другой механизм. Но сообществу таки надо только чтобы было @inject initlater... Лучше бы гугл научил людей работать с состоянием, а не бороться с пересозданием зависимостей, когда activity пересоздалась...
А как настроить такую тему в студии? ))
@AndroidBroadcast
3 жыл бұрын
Что именно?
@EvgeniyGooDiBunakov
3 жыл бұрын
@@AndroidBroadcast цвета
@AndroidBroadcast
3 жыл бұрын
Это стандартная темна тема Darcula + плагин plugins.jetbrains.com/plugin/10080-rainbow-brackets
На тему опроса, почему не велик интерес к роликам - да просто некогда. Нужна отдельная кружка чаю, чтобы сесть и посмотреть.
@AndroidBroadcast
3 жыл бұрын
😔
13:30 А я пришел к рекурсии.. о_О
@VoidObj
2 жыл бұрын
Теста ради заменил ваш else на else -> DaggerAppComponent.builder().contextModule(ContextModule(this)).build() и все взлетело. Понятное дело, что это ужас и так делать нельзя. Забавно..
@VoidObj
2 жыл бұрын
ГОСПОДИЯИДИОТ... 🤦♂️🤦♂️🤦♂️🤦♂️🤦♂️ Всего-то в манифесте забыл прописать.. А ведь говорили "Не забудьте прописать в манифесте"!
kapt больше не актуален, рекомендуется миграция на ksp
@AndroidBroadcast
4 ай бұрын
Dagger с KSP на момент написания комментария находится в экспериментальном статусе
@user-fg3wl4xu9d
4 ай бұрын
@@AndroidBroadcast у меня с kapt при добавлении в проект постоянно какие-то проблемы с версиями, а с ksp так легко всё прошло - быстро, как в первый раз)
Не понимаю куче восхитительных отзывов. Начало нормально , но потом что-то намудрил, чёрт ногу сломит....
kzread.info/dash/bejne/Y5iD1cefYr3ggZs.html 10.09. появилась проблема. не видит DaggerAppComponent . 10 раз перепроверил код. ощущение что с тех пор чтото изменилось в гредле или не хватает чего то на уровне гредл проджекта. версия 2,44,2 + kapt {correctErrorTypes = true} тоже не помогло =(
@AndroidBroadcast
Жыл бұрын
Класс генерируется вообще?
@sfsd9507
Жыл бұрын
@@AndroidBroadcast класс DaggerAppComponent не генерируется. при попытке его вписать ИДЕ предлагает только: DaggerCollections и DaggerGenerated. аннотации распознает, dagger.аннотацию импортирует в документе
@sfsd9507
Жыл бұрын
@@AndroidBroadcast так... завел. добавил к аннотации @Component аннотацию @Singleton, не знаю на сколько это верное решение
@AndroidBroadcast
Жыл бұрын
Надо смотреть настройку проекта, а не только код
@AndroidBroadcast
Жыл бұрын
@@sfsd9507 Лучше задайте вопрос в t.me/android_broadcast_talks