简体   繁体   中英

Dagger injection ViewModel Factory compile time error (dependency cycle in dagger)

I receive following error message from dagger at compile time. It finds a dependency cycle in dagger :

public abstract interface AppComponent extends dagger.android.AndroidInjector<com.sample.android.storytel.StorytelApplication> {
            ^
  androidx.lifecycle.ViewModelProvider.Factory is injected at
      com.sample.android.storytel.ui.DetailFragment.factory
  com.sample.android.storytel.ui.DetailFragment is injected at
      com.sample.android.storytel.di.DetailModule.providePost$app_debug(fragment)
  com.sample.android.storytel.domain.Post is injected at
      com.sample.android.storytel.viewmodels.DetailViewModel.Factory(…, post)
  com.sample.android.storytel.viewmodels.DetailViewModel.Factory is injected at
      com.sample.android.storytel.di.DetailModule.bindViewModelFactory$app_debug(factory)
  androidx.lifecycle.ViewModelProvider.Factory is injected at
      com.sample.android.storytel.ui.DetailFragment.factory
  com.sample.android.storytel.ui.DetailFragment is injected at
      dagger.android.AndroidInjector.inject(T) [com.sample.android.storytel.di.AppComponent → com.sample.android.storytel.di.ActivityBindingModule_MainActivity$app_debug.MainActivitySubcomponent → com.sample.android.storytel.di.DetailModule_DetailFragment$app_debug.DetailFragmentSubcomponent]

Here is my DetailModule :

@Module
abstract class DetailModule {

    @ContributesAndroidInjector
    internal abstract fun detailFragment(): DetailFragment

    @Binds
    internal abstract fun bindViewModelFactory(factory: DetailViewModel.Factory): ViewModelProvider.Factory

    @Module
    companion object {

        @Provides
        @JvmStatic
        internal fun providePost(fragment: DetailFragment): Post =
            DetailFragmentArgs.fromBundle(fragment.arguments!!).post
    }
}

Here is AppComponent :

@Singleton
@Component(
    modules = [ActivityBindingModule::class,
        AndroidSupportInjectionModule::class,
        Network::class,
        BaseModule::class]
)
interface AppComponent : AndroidInjector<StorytelApplication> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }
}

Here is ActivityBindingModule :

@Module
abstract class ActivityBindingModule {

    @ContributesAndroidInjector(
        modules = [MainModule::class,
            DetailModule::class]
    )
    internal abstract fun mainActivity(): MainActivity
}

And this is my DetailViewModel Factory :

/**
     * Factory for constructing DetailViewModel with parameter
     */
    class Factory @Inject constructor(
        private val useCase: DetailUseCase,
        val post: Post
    ) : ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(DetailViewModel::class.java)) {
                @Suppress("UNCHECKED_CAST")
                return DetailViewModel(useCase, post) as T
            }
            throw IllegalArgumentException("Unable to construct viewmodel")
        }
    }

I have injected factory at my DetailFragment :

class DetailFragment @Inject
constructor() // Required empty public constructor
    : DaggerFragment() {

    @Inject
    lateinit var factory: DetailViewModel.Factory

    private val viewModel: DetailViewModel by lazy {
        ViewModelProviders.of(this, factory)
            .get(DetailViewModel::class.java)
    }
}

Here you can find source code : https://github.com/Ali-Rezaei/Colors

I change my providePost method by passing MainActivity as parameter instead of DetailFragment, and problem resolved :

        @Provides
        @JvmStatic
        internal fun providePost(activity: MainActivity): Post {
            val navHostFragment = activity.supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment)
            val fragment = navHostFragment?.childFragmentManager?.fragments?.get(0);
            return DetailFragmentArgs.fromBundle(fragment?.arguments!!).post
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM