Skip to main content

Inject ViewModels

Koject allows you to easily inject ViewModels into your Android application.

Setup for ViewModels

Add the appropriate dependencies for the injection target:

dependencies {
// Inject ViewModel into Activity
implementation("com.moriatsushi.koject:koject-android-activity:1.3.0")
// Inject ViewModel into Fragment
implementation("com.moriatsushi.koject:koject-android-fragment:1.3.0")
// ViewModelFactory only
implementation("com.moriatsushi.koject:koject-android-viewmodel:1.3.0")
}

Please also refer to the Setup document.

Using ViewModels

To define a ViewModel, specify the @ViewModelComponent and @Provides annotations. You can use constructor injection as with other types:

@Provides
@ViewModelComponent
class TopViewModel(
private val userRepository: UserRepository,
private val contentRepository: ContentRepository,
): ViewModel() {
/* ... */
}

When using ViewModels, use the ComponentActivity.lazyViewModels() function:

class TopActivity : ComponentActivity() {
private val viewModel: TopViewModel by lazyViewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
/* ... */
}
}

For fragments, use the Fragment.lazyViewModels() function:

class TopFragment : Fragment() {
private val viewModel: TopViewModel by lazyViewModels()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
/* ... */
}
}
LINK

Refer to the documentation to inject ViewModels in Jetpack Compose.

MIGRATION (VERSION 1.3.0)

As of version v1.3.0, injectViewModels() has been renamed to lazyViewModels():

// Until v1.1.0
private val viewModel: TopViewModel by injectViewModels()

// Since v1.3.0
private val viewModel: TopViewModel by lazyViewModels()

Working with SavedStateHandle

SavedStateHandle is used to save ViewModel state. Koject allows you to inject SavedStateHandle out of the box.

@Provides
@ViewModelComponent
class SavedStateViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
/* ... */
}
class TopActivity : ComponentActivity() {
private val viewModel: SavedStateViewModel by lazyViewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
/* ... */
}
}

Inject ViewModel's CoroutineScope

Types with ViewModelComponent annotations can only be injected into ViewModel and can inject ViewModel's CoroutineScope. The @ViewModelCoroutineScope qualifier is required to use the CoroutineScope.

@Provides
@ViewModelComponent
class ViewModelHelper(
@ViewModelCoroutineScope
val scope: CoroutineScope // same as ViewModel.viewModelScope
) {
/* ... */
}

@Provides
@ViewModelComponent
class SomeViewModel(
val helper: ViewModelHelper
): ViewModel() {
/* ... */
}
LINK

Check the Android components documentation for all available components for Android.