Inject only certain params in constructor

时光总嘲笑我的痴心妄想 提交于 2020-06-12 06:52:27

问题


I have the presenter

class PhonePresenter @Inject constructor(
    private val preference: DataPreference,
    private val ioScheduler: Scheduler = Schedulers.io())

ioScheduler is a default parameter. I want to inject only preference: DataPreference. Now I have the exception

[dagger.android.AndroidInjector.inject(T)] io.reactivex.Scheduler cannot be provided without an @Provides-annotated method.

Is there any way to define parameters which I want to inject in a constructor?


回答1:


Make inject constructor with secondary constructor

class PhonePresenter(
    private val preference: DataPreference,
    private val ioScheduler: Scheduler) {        
    @Inject consturctor(preference: DataPreference):this(perference, Schedulers.io())
}



回答2:


Dagger is responsible for injection, let it do it's job. Don't use default parameters (Dagger doesn't care), this will force you to make concious decisions about your dependencies.

Two approaches come to mind:

1. Use Dagger to inject

Create a qualifier so Dagger can diferentiate between types of schedulers you might want to inject and a module that provides default IO scheduler.

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@MustBeDocumented
annotation class ForIo

@Module
class SchedulerModule {
     @Provides @ForIo
     fun provideIoScheduler() : Scheduler = Schedulers.io()
}

class PhonePresenter @Inject constructor(
    private val preference: DataPreference,
    @ForIo private val ioScheduler: Scheduler
) { ... }

Add SchedulerModule to your component as usual.

The correct way to supply different arguments is to use a different component with different modules specialized e.g. for testing. Or when testing you'll call the constructor manually.

2. Avoid Dagger in this case

Alternatively you can remove the IO scheduler from constructor parameters. The names suggests it's never going to be anything else than Schedulers.io() so it makes little sense to make it parameterized; make it an implementation detail instead.

class PhonePresenter @Inject constructor(private val preference: DataPreference) { 
    private val ioScheduler = Schedulers.io()

    ... 
}


来源:https://stackoverflow.com/questions/47961375/inject-only-certain-params-in-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!