简体   繁体   中英

Dagger failing to inject Application context

I have dagger set up to manage fragments and viewmodels. I need to pass application context to my view models in order to instantiate and communicate with the repository class. When I try to do this I get an error from dagger stating:

    error: [Dagger/DependencyCycle] Found a dependency cycle:
public abstract interface AppComponent {
                ^
      com.example.framework.BaseApplication is injected at
          com.example.di.AppModule.provideAppContext(application)
      com.example.framework.BaseApplication is injected at
          com.example.di.MainViewModelModule.provideMainViewModelFactory(application, �)
      androidx.lifecycle.ViewModelProvider.Factory is injected at
          com.example.framework.presentation.common.MainFragmentFactory(viewModelFactory)
      com.example.framework.presentation.common.MainFragmentFactory is injected at
          com.example.framework.presentation.main.MainActivity.fragmentFactory
      com.example.framework.presentation.main.MainActivity is injected at

I am new to dagger so I am struggling to identify the root cause of this issue and how to implement a fix. Apologies for the amount of code in this question but dagger has a number of classes where the problem could be.

APP COMPONENT

@Component(
    modules = [
        AppModule::class,
        MainViewModelModule::class,
        MainFragmentFactoryModule::class
    ]
 )
 interface AppComponent {

 @Component.Builder
  interface Builder {

      @BindsInstance
      fun application(application: Application): Builder
      fun build(): AppComponent
  }

fun inject(mainActivity: MainActivity)

APP MODULE

@ExperimentalCoroutinesApi
@FlowPreview
@Module
object AppModule {

@JvmStatic
@Provides
@Singleton
fun provideAppContext(application: BaseApplication): BaseApplication{
    return application
}

VIEW MODEL MODULE

@ExperimentalCoroutinesApi
@FlowPreview
@Module
object MainViewModelModule {

@Singleton
@JvmStatic
@Provides
fun provideMainViewModelFactory(
        application: BaseApplication,
        editor: SharedPreferences.Editor,
        sharedPreferences: SharedPreferences
): ViewModelProvider.Factory{
    return MainViewModelFactory(
            application = application,
            editor = editor,
            sharedPreferences = sharedPreferences
    )
}

VIEW MODEL FACTORY

@FlowPreview
@ExperimentalCoroutinesApi
@Singleton
class MainViewModelFactory
@Inject
constructor(
    private val application: BaseApplication,
    private val editor: SharedPreferences.Editor,
    private val sharedPreferences: SharedPreferences
) : ViewModelProvider.Factory {

override fun <T : ViewModel> create(modelClass: Class<T>): T {
    return when(modelClass){

        ViewModelUsers::class.java -> {
            ViewModelUsers(
                    application = application,
                    editor = editor,
                    sharedPreferences = sharedPreferences
            ) as T
        }

VIEW MODEL

@ExperimentalCoroutinesApi
@FlowPreview
@Singleton
class ViewModelUsers
@Inject
constructor(
        application: BaseApplication,
        private val editor: SharedPreferences.Editor,
        sharedPreferences: SharedPreferences
): ViewModel() {
    private var repoUsers = RepoUsers(application)

Many ways to fix it but the simple way is you should change to BaseApplication and remove AppModule class because it already provides by @BindsInstance annotation

@Component(
    modules = [
        MainViewModelModule::class,
        MainFragmentFactoryModule::class
    ]
 )
 interface AppComponent {

 @Component.Builder
  interface Builder {

      @BindsInstance
      fun application(application: BaseApplication): Builder
      fun build(): AppComponent
  }

fun inject(mainActivity: MainActivity)

将存储库注入视图模型解决了这个问题,而不是尝试通过链传递应用程序上下文。

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