Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Connecting The Dots :: InjectingViewModelFactory.kt
@Reusable
class InjectingSavedStateViewModelFactory @Inject constructor(
private val assistedFactories: Map<Class<out ViewModel>, @JvmSuppressWildcards AssistedSavedStateViewModelFactory<out ViewModel>>,
private val viewModelProviders: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) {
/**
* Creates instance of ViewModel either annotated with @AssistedInject or @Inject and passes dependencies it needs.
*/
fun create(owner: SavedStateRegistryOwner, defaultArgs: Bundle? = null) =
object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
override fun <T : ViewModel?> create(
key: String,
modelClass: Class<T>,
handle: SavedStateHandle
): T {
val viewModel =
createAssistedInjectViewModel(modelClass, handle)
?: createInjectViewModel(modelClass)
?: throw IllegalArgumentException("Unknown model class $modelClass")
try {
@Suppress("UNCHECKED_CAST")
return viewModel as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
/**
* Creates ViewModel based on @AssistedInject constructor and its factory
*/
private fun <T : ViewModel?> createAssistedInjectViewModel(
modelClass: Class<T>,
handle: SavedStateHandle
): ViewModel? {
val creator = assistedFactories[modelClass]
?: assistedFactories.asIterable().firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
?: return null
return creator.create(handle)
}
/**
* Creates ViewModel based on regular Dagger @Inject constructor
*/
private fun <T : ViewModel?> createInjectViewModel(modelClass: Class<T>): ViewModel? {
val creator = viewModelProviders[modelClass]
?: viewModelProviders.asIterable().firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
?: return null
return creator.get()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.