Skip to content

Instantly share code, notes, and snippets.

@naltynbekkz
Created April 25, 2020 19:00
Show Gist options
  • Save naltynbekkz/92510426d6393b3a4562156735468ed0 to your computer and use it in GitHub Desktop.
Save naltynbekkz/92510426d6393b3a4562156735468ed0 to your computer and use it in GitHub Desktop.
@Reusable
class ViewModelProviderFactory @Inject constructor(
private val assistedFactories: Map<Class<out ViewModel>, @JvmSuppressWildcards ViewModelAssistedFactory<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()
}
}
interface ViewModelAssistedFactory<T : ViewModel> {
fun create(savedStateHandle: SavedStateHandle): T
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment