Как понять dagger?

Читаю информацию, вроде легче лёгкого, но как смотрю примеры в реальных проектах, вообще не понимаю как это работает Мб у кого в закладке лежит та самая статейка, которая помогла вам в своё время с кинжалом разобраться? Android kotlin


Ответы (1 шт):

Автор решения: ЮрийСПб

Лично я не видел ни одной статьи, которая бы описывала DI в простых словах, не усложняя текст абстракциями. Засим вот как я примерно объясняю обычно эту штуку совсем поп простому.

Всё что делают DI либы (Dagger, Koin, Toothpick etc) - создают единственный экземпляр класса (Component в Dagger), который хранит в себе ссылки на экземпляры других классов (класс для запросов в БД, сеть, префы etc) или имеет методы для их получения/создания. Всё это нужно в основном для простоты и унификации получения ссылок на эти классы.

Описанное выше можно усложнять, указывая что вот такой-то класс должен иметь всего один экземпляр на приложение, а вот этот должно быть возможно создавать каждый раз новый. Ну и вся эта система позволяет более гибко настраивать где и какие экземпляры классов нужны.

Далее уже, при использовании той или иной либы для DI надо смотреть как в ней создаются нужные классы DI и как прописывается получение экземпляров ваших классов (работа с БД, сетью, префами etc).

Например в Dagger экземпляр класса, в котором всё находится - это класс/интерфейс, помеченный аннотацией @Component. В аннотацию передаются классы/интерфейсы, помеченные аннотацией @Module. В последней нет никакой магии, это просто сделано для принуждения программистов к разбиению зависимотей по группам. В модулях вы уже и описываете, как создавать экземпляров ваших классов (работа с БД, сетью, префами etc). В Dagger это будут методы, возвращающие экземпляры ваших классов. Методы надо пометить аннотацией @Provides.

Собственно всё. Теперь вы где-то (обычно в onCreate класса Application) создаёте экземпляр класса помеченного аннотацией @Component примерно так: ИМЯ_КЛАССА_С_АННОТАЦИЕЙ_Component.create(). Этот экземпляр помещаете в публичную статическую переменную класса Application (т.е. получается что-то типа singleton-а), чтобы можно было отовсюду эту переменную получать. Теперь вы можете из любого места в коде писать так: MyDbClass mdb = MyApplicationClass.component.getMyDbClass();. Или помечать MyDbClass mdb аннотацией @Inject и вызывать MyApplicationClass.component.inject(this);.

Как это всё работает? Очень просто - на кодогенерации по аннотациям. Когда вы запускаете сборку проекта, на одной из стадий сборки запускается парсер аннотаций, которому в либе Dagger объяснено какой код надо сгенерировать по аннотациям из этой библиотеки. И весь скучный код создания экземпляров классов будет сгенерирован автоматически.

→ Ссылка