Skip to content Skip to sidebar Skip to footer

How I Can Add View Model In Module?

In Dagger, how can I add a model to Module? For example I added the presenter in the following way: @Module class AboutModule(val appContext: Context) { @FragmentScope @Pr

Solution 1:

I solved my problem with next solution:

@ModuleclassAboutModule(val appContext: Context) {

    @FragmentScope@ProvidesfunprovideFactory(): AboutViewModelFactory {
        return AboutViewModelFactory(appContext)
    }
}

And in fragment write smth like this: class AboutFragment : BaseFragment(), OnItemClickListener {

lateinitvar viewModel: AboutViewModel
@Injectlateinitvar viewModelFactory: AboutViewModelFactory

overridefunonCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    injectDependencies()

    viewModel = ViewModelProviders
        .of(this, viewModelFactory)
        .get(AboutViewModel::class.java)
}

privatefuninjectDependencies() {
    activity?.let {
        DaggerAboutComponent.builder().aboutModule(AboutModule(it)).build().inject(this)
    }
}

Nice advise: https://stackoverflow.com/a/60884492/6387618

Solution 2:

To retrieve the ViewModel from the component without Map Multibinding, you can do:

@Singleton@Component(modules=[...])interfaceSingletonComponent{
    val aboutListViewModel: Provider<AboutListViewModel>
}

Which works when you can use @Inject constructor:

// unscopedclassAboutListViewModel@Injectconstructor(): ViewModel() {
}

Because now you can do:

classAboutListFragment: Fragment(R.layout.about_list_fragment) {
    privateval viewModel by viewModels<AboutListViewModel>() {
        object: ViewModelProvider.Factory {
            overridefuncreate(clazz: Class<ViewModel>) {
                return (requireActivity().application as MyApplication).component.aboutListViewModel.get()
            }
        }
    }
}

Which might seem tacky, but you can hide all of that in an extension function

fun<T: ViewModel> Fragment.fragmentViewModels(viewModelCreator: SingletonComponent.() -> T) = viewModels<T> {
    object: ViewModelProvider.Factory {
        overridefuncreate(clazz: Class<ViewModel>) {
            val component = requireActivity().application as MyApplication).component
            return viewModelCreator(component)
        }
    }
}        

Because now you can do

classAboutListFragment: Fragment(R.layout.about_list_fragment) {
    privateval viewModel by fragmentViewModels<AboutListViewModel> { component ->
        component.aboutListViewModel().get()
    }
}

And this would work even without map multibinding. If you need a SavedStateHandle, you'd need AssistedInject, but if you don't want that, it'll be easier when Dagger-Hilt is stable (then it'll be as simple as @ViewModelInject and @Assisted).

Solution 3:

ViewModels are injected using Dagger Multibindings

refer to this medium article: https://medium.com/chili-labs/android-viewmodel-injection-with-dagger-f0061d3402ff

context can be injected by providing in the AppModule class.

Post a Comment for "How I Can Add View Model In Module?"