Dependency Injection of ViewModel with Dagger 2

Below is a sample Android code for DI of VM with Dagger 2

In Kotlin

@Singleton
class ViewModelFactory @Inject constructor(private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>) :
ViewModelProvider.Factory {
override
fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}
@Module
abstract class ViewModelModule {
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
@Binds
internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@IntoMap
@ViewModelKey(ViewModel1::class)
internal abstract fun myViewModel1(viewModel: ViewModel1): ViewModel
@Binds
@IntoMap
@ViewModelKey(MyViewModelWithConstructor::class)
internal abstract fun myViewModelWithConstructor(fetchDataUseCase1: FetchDataUseCase1): ViewModel {
return MyViewModelWithConstructor(fetchDataUseCase1)
}
//Add more ViewModels here
}

In Java

public class ViewModelFactory implements ViewModelProvider.Factory {

private final MyViewModel mMyViewModel;

@Inject
public ViewModelFactory(MyViewModel myViewModel) {
mMyViewModel = myViewModel;
}

@SuppressWarnings(“unchecked”)
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
ViewModel viewModel;
if (modelClass == MyViewModel.class) {
viewModel = mMyViewModel;
}
else {
throw new RuntimeException(“unsupported view model class: “ + modelClass);
}

return (T) viewModel;
}
}
@Module
public class ViewModelModule {

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}

@Provides
ViewModelFactory viewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> providerMap) {
return new ViewModelFactory(providerMap);
}

@Provides
@IntoMap
@ViewModelKey(MyViewModel1.class)
ViewModel viewModel1(FetchDataUseCase1 fetchDataUseCase1) {
return new MyViewModel1(fetchDataUseCase1);
}
}