Search code examples
androidmvvmdependency-injectionkotlinviewmodel

How to initialize/inject generic ViewModel in BaseActivity by Koin injection on Android/Kotlin App


I'm building the architecture of a new Android application using Kotlin and Android Architecture Components (ViewModel, LiveData) and I'm also using Koin as my dependency injection provider.

The problem is that I'm not been able to initialize the ViewModel in a generic way inside my BaseActivity via koin injection. The current code looks like this:

abstract class BaseActivity<ViewModelType : ViewModel> : AppCompatActivity() {

    // This does not compile because of the generic type
    private val viewModel by lazy {
        // Koin implementation to inject ViewModel
        getViewModel<ViewModelType>()
    }

    @CallSuper
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Fabric.with(this, Crashlytics())
    }

    /**
     * Method needed for Calligraphy library configuration
     */
    @CallSuper
    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase))
    }
}

I'd like to know if is there a way to do this in Kotlin because I'm pretty sure I would be able to do in Java easily. Thanks.


Solution

  • The solution was provided by the koin team in version 0.9.0-alpha-11 and the final code looks like this:

    open class BaseActivity<out ViewModelType : BaseViewModel>(clazz: KClass<ViewModelType>) :
        AppCompatActivity() {
    
        val viewModel: ViewModelType by viewModel(clazz)
    
        fun snackbar(message: String?) {
            message?.let { longSnackbar(find(android.R.id.content), it) }
        }
    
        fun toast(message: String?) {
            message?.let { longToast(message) }
        }
    }