Size: a a a

2019 October 31

ИЯ

Илья Ярлыкин in Dagger 2
Народ, а стоит ли вообще создавать компоненты/модули вообще для каждого класса? Это же делает код многословным.
В каких случаях писать зависимости на di?
источник

SV

Sviat Volkov in Dagger 2
что значит для каждого класса?
источник

SV

Sergey Vasilchenko in Dagger 2
Илья Ярлыкин
Народ, а стоит ли вообще создавать компоненты/модули вообще для каждого класса? Это же делает код многословным.
В каких случаях писать зависимости на di?
модули для каждого нет, только для внешних где у вас нет доступа к конструктору
источник

ИЯ

Илья Ярлыкин in Dagger 2
Sviat Volkov
что значит для каждого класса?
абсолютно для каждого класса, у которого есть зависимости.
источник

ИЯ

Илья Ярлыкин in Dagger 2
я не понимаю в каких случаях применять даггер
источник

SV

Sviat Volkov in Dagger 2
если не понимаете, то мб он и не нужен
источник

SV

Sviat Volkov in Dagger 2
компонента это как дерево зависимостей, представляет собой какой-то логический кусок. допустим NetworkComponent  которая создает все нетворк зависимости.

Можно экран выделить в логический кусок
допустим LoginComponent и там лежат презентер\валидаторы и прочее что живет в рамках экрана логина.

Модули это просто классы которые описывают как создать объект
источник

SV

Sviat Volkov in Dagger 2
каждый класс сам по себе это слишком мелкая часть чтобы делать под нее компоненту
источник

SV

Sviat Volkov in Dagger 2
начать стоит с одной компоненты. AppComponent и дальше уже постепенно разберетесь как делить свой граф зависимостей по кускам (некоторые не делят годами и рождаются компоненты-монстры на 100ккк строк 😉 )
источник

ИЯ

Илья Ярлыкин in Dagger 2
Вот самый обычный кейс - внутри презентера создаются интерактор. Внутри интерактора - энтити и  сторейдж. Расписывать все внутренние классы - в модуле?
источник

ИЯ

Илья Ярлыкин in Dagger 2
Sviat Volkov
начать стоит с одной компоненты. AppComponent и дальше уже постепенно разберетесь как делить свой граф зависимостей по кускам (некоторые не делят годами и рождаются компоненты-монстры на 100ккк строк 😉 )
потом для каждого нужного классы вызывать внутри метода компоненты inject?
источник

SV

Sviat Volkov in Dagger 2
логика создания объектов выносится в модули, компонента это модули связывает между собой через Component( modules = )
источник

SV

Sviat Volkov in Dagger 2
Илья Ярлыкин
потом для каждого нужного классы вызывать внутри метода компоненты inject?
инжектить надо в конструктор
источник

ИЯ

Илья Ярлыкин in Dagger 2
я просто думал, что это немного по-другому устроено.
источник

SV

Sviat Volkov in Dagger 2
думаю вам стоит начать с простых семплов и глядя в сгенерированный код двигаться к более сложным
источник

ИЯ

Илья Ярлыкин in Dagger 2
Sviat Volkov
думаю вам стоит начать с простых семплов и глядя в сгенерированный код двигаться к более сложным
стоит ли инжектить зависимости через di абсолютно в каждом классе?
источник

ИЯ

Илья Ярлыкин in Dagger 2
например, у интеракторов зависимости - только modelStorage(бд) и modelProvider(апи). У каждого интерактора они отличаются.
Стоит ли плодить кучу кода?

Может как-то можно написать универсальный модуль?
источник
2019 November 03

M

Max in Dagger 2
Здравствуйте. Сейчас разбираюсь с даггером, а конкретно его связкой с mvvm. От гугла есть хороший пример, где используется одна фабрика для всех viewmodel и это отлично работает, если все зависимости инжектятся к конструктор вьюмоделей. Но этот способ не подходит, если нужно передать во viewmodel параметр из фрагмента/активити.
Пока придумал только один вариант - сделать в аппликейшн статическую ссылку на AppComponent, через нее получать сабкомпонент

fun createUserComponent(user: UserModule): UserComponent

, передавая в него модуль, который принимает в конструкторе нужный параметр и имеет Provide-метод, создающий viewModel.

@Module
class UserModule(val id: Int) {
   @Provides
   fun provideUserViewModel(): UserViewModel{
       return UserViewModel(id)
   }
}


Далее во вьюмодели сделать фабрику с полем нужного параметра(id)

class UserViewModel (val id: Int): ViewModel() {

   class UserFactory @Inject constructor(): ViewModelProvider.NewInstanceFactory() {
       var id: Int? = null
       override fun <T : ViewModel?> create(modelClass: Class<T>): T {
           return App.component.createUserComponent(UserModule(id!!)).getUserVM() as T
       }
   }

}


Потом заинжектить во фрагмент фабрику, в onCreateView присвоить ей нужный параметр и получить вьюмодель

@Inject
lateinit var userFactory: UserViewModel.UserFactory

userFactory.id = arguments!!.getInt("id")
viewModel = ViewModelProviders.of(this, userFactory).get(UserViewModel::class.java)


В итоге все работает, но выглядит уж больно коряво и смахимвает на костыль. Как минимум читал, что передавать в компонент модули это нехорошая практика, мол есть @BindsInstance, но тут от него толку нет. И статическая ссылка на AppComponent тоже не айс. Подскажите, может есть вариант посимпатичнее.
источник
2019 November 04

АЕ

Алексей Ершов in Dagger 2
Max
Здравствуйте. Сейчас разбираюсь с даггером, а конкретно его связкой с mvvm. От гугла есть хороший пример, где используется одна фабрика для всех viewmodel и это отлично работает, если все зависимости инжектятся к конструктор вьюмоделей. Но этот способ не подходит, если нужно передать во viewmodel параметр из фрагмента/активити.
Пока придумал только один вариант - сделать в аппликейшн статическую ссылку на AppComponent, через нее получать сабкомпонент

fun createUserComponent(user: UserModule): UserComponent

, передавая в него модуль, который принимает в конструкторе нужный параметр и имеет Provide-метод, создающий viewModel.

@Module
class UserModule(val id: Int) {
   @Provides
   fun provideUserViewModel(): UserViewModel{
       return UserViewModel(id)
   }
}


Далее во вьюмодели сделать фабрику с полем нужного параметра(id)

class UserViewModel (val id: Int): ViewModel() {

   class UserFactory @Inject constructor(): ViewModelProvider.NewInstanceFactory() {
       var id: Int? = null
       override fun <T : ViewModel?> create(modelClass: Class<T>): T {
           return App.component.createUserComponent(UserModule(id!!)).getUserVM() as T
       }
   }

}


Потом заинжектить во фрагмент фабрику, в onCreateView присвоить ей нужный параметр и получить вьюмодель

@Inject
lateinit var userFactory: UserViewModel.UserFactory

userFactory.id = arguments!!.getInt("id")
viewModel = ViewModelProviders.of(this, userFactory).get(UserViewModel::class.java)


В итоге все работает, но выглядит уж больно коряво и смахимвает на костыль. Как минимум читал, что передавать в компонент модули это нехорошая практика, мол есть @BindsInstance, но тут от него толку нет. И статическая ссылка на AppComponent тоже не айс. Подскажите, может есть вариант посимпатичнее.
Assisted inject посмотрите, может понравится
источник
2019 November 05

M

Max in Dagger 2
Алексей Ершов
Assisted inject посмотрите, может понравится
Спасибо!
источник