Created
April 25, 2020 19:00
-
-
Save naltynbekkz/92510426d6393b3a4562156735468ed0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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