Inject only certain params in constructor
Make inject constructor with secondary constructor
class PhonePresenter(
private val preference: DataPreference,
private val ioScheduler: Scheduler) {
@Inject constructor(preference: DataPreference) : this(preference, Schedulers.io())
}
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()
...
}