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