I understand that you can use `Assisted Injection`...
# dagger
d
I understand that you can use
Assisted Injection
to pass runtime parameters into objects being injected. What I haven't been able to figure out is how to use that (or another mechanism) to choose the type of object being injected based on a runtime parameter. For example, without using DI I might do something like this
Copy code
class RepoDataSourceScreenViewModel: ViewModel() {
    var isSimulated = lookupIsSimulated()

    val repository = ComponentRepository(isSimulated)
    
    // This would be backed by a DB/sharedPref lookup
    private fun lookupIsSimulated(): Boolean  = false
    
}

class ComponentRepository(val isSimulated: Boolean) {
    val dataSource = if(isSimulated) RealComponentDataSource() else SimComponentDataSource()
}

abstract class ComponentDataSource()
class RealComponentDataSource() {}
class SimComponentDataSource() {}
Is there an equivalent be in a Dagger/Hilt environment?
j
Put the boolean in the graph, change the implementation of your provider to use the boolean to conditionally return one of the two types. If the types are also in the graph, your provider should request them as
Provider<T>
arguments
d
Thanks Jake. Does this implementation match up with what you were suggesting?
Copy code
@Module
@InstallIn(SingletonComponent::class)
class ConfigModule {
    @Provides
    @Singleton
    fun provideSimulationConfig(): SimulationConfig {
        return SimulationConfig(false)
    }
}

@Module
@InstallIn(ActivityRetainedComponent::class)
class RepoModule {
    @Provides
    fun provideComponentRepository(dataSource: ComponentDataSource): ComponentRepository {
        return ComponentRepository(dataSource)
    }

    @Provides
    fun provideDataSource(simulationConfig: SimulationConfig): ComponentDataSource {
        return if (simulationConfig.isEnabled) {
            SimComponentDataSource()
        } else {
            RealComponentDataSource()
        }
    }
}
Then the viewmodel injects the repository and gets the data source injected automatically. The SimulationConfig would be updated elsewhere within the app based on the persistent state
j
Seems good