Skip to content

Instantly share code, notes, and snippets.

@m4xp1
Last active June 26, 2020 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m4xp1/9097ef3988b702b9764c8f65b52454e0 to your computer and use it in GitHub Desktop.
Save m4xp1/9097ef3988b702b9764c8f65b52454e0 to your computer and use it in GitHub Desktop.
ViewModelFactory
/*
* Класс специфичный для конкретной фичи, лежит в пакете screen некоего фиче модуля.
*/
class FeatureActivity : AppCompatActivity() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private val viewModel: FeatureViewModel1 by viewModels { viewModelFactory }
}
/*
* Класс специфичный для конкретной фичи, лежит в пакете di некоего фиче модуля.
*/
@ActivityScope
@Subcomponent(
modules = [
FeatureViewModelsModule::class,
ViewModelFactoryModule::class
]
)
interface FeatureComponent {
fun inject(instance: FeatureActivity)
@Subcomponent.Factory
interface Factory {
fun createComponent(): FeatureComponent
}
}
/*
* Класс специфичный для конкретной фичи, лежит в пакете di некоего фиче модуля.
*/
@Module
class FeatureViewModelsModule {
@Provides
@IntoMap
@ViewModelKey(FeatureViewModel1::class)
fun featureViewModel1(viewModel: FeatureViewModel1): ViewModel = viewModel
@Provides
@IntoMap
@ViewModelKey(FeatureViewModel2::class)
fun featureViewModel2(viewModel: FeatureViewModel2): ViewModel = viewModel
}
/*
* Класс общий для всех фиче модулей в проекте. Например лежит в модуле viewmodel-di в пакете di.viewmodel.
* Остальные фичемодули используют viewmodel-di в качестве зависимости.
*/
class ViewModelFactory @Inject constructor(
private val providers: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(type: Class<T>): T {
val provider = providers[type] ?: providers.entries.find {
type.isAssignableFrom(it.key)
}?.value ?: throw IllegalArgumentException("Unregistered ViewModel class: $type.")
try {
@Suppress("UNCHECKED_CAST")
return provider.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
/*
* Класс общий для всех фиче модулей в проекте. Например лежит в модуле viewmodel-di в пакете di.viewmodel.
* Остальные фичемодули используют viewmodel-di в качестве зависимости.
*/
@Module
abstract class ViewModelFactoryModule {
@Multibinds
abstract fun viewModels(): Map<Class<out ViewModel>, ViewModel>
@Binds
@ActivityScope // Важно сохранить скоп чтобы каждый раз не пересоздавать фабрику при пересоздании активности.
abstract fun viewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
/*
* Класс общий для всех фиче модулей в проекте. Например лежит в модуле viewmodel-di в пакете di.viewmodel.
* Остальные фичемодули используют viewmodel-di в качестве зависимости.
*/
@MapKey
@Target(FUNCTION)
@Retention(RUNTIME)
annotation class ViewModelKey(val type: KClass<out ViewModel>)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment