匕首:如果没有@Inject构造函数或@Provides注释的方法,则无法提供

时间:2019-08-25 00:10:31

标签: android kotlin dependency-injection dagger-2 dagger

我正在尝试将MainActivity的上下文注入方法中。这是我的Dagger设置的简化版本:

AppComponent

@Singleton
@Component(
    modules = [
        AndroidInjectionModule::class,
        AppModule::class,
        MainActivityModule::clas
    ]
)
interface AppComponent : AndroidInjector<MyApp> {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }
}

AppModule

class AppModule {
    @Singleton
    @Provides
    fun provideRepository(context: Context) = Repository(context)
}

MainActivityModule

@Suppress("unused")
@Module
abstract class MainActivityModule {
    @ContributesAndroidInjector
    abstract fun contributeMainActivity(): MainActivity


    @Binds
    abstract fun bindsMainActivityContext(mainActivity: MainActivity): @ActivityContext Context
}

正如您在provideRepository()中所看到的,应该注入一个参数上下文。每当我构建应用程序时,都会出现以下错误:

error: [Dagger/MissingBinding] app.example.myapp.MainActivity cannot be provided without an @Inject constructor or an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
public abstract interface AppComponent extends dagger.android.AndroidInjector<app.example.myapp.MyApp> {
                ^
  A binding with matching key exists in component: app.example.myapp.injection.module.MainActivityModule_ContributeMainActivity.MainActivitySubcomponent
      app.example.myapp.MainActivity is injected at
          app.example.myapp.injection.module.MainActivityModule.bindsMainActivityContext(mainActivity)
      @app.example.myapp.injection.module.ActivityContext android.content.Context is injected at
          app.example.myapp.injection.module.AppModule.provideTokenRepository(…, context)
      app.example.myapp.repository.interfaces.ITokenRepository is injected at
          app.example.myapp.ui.signin.SignInViewModel(repository)
      app.example.myapp.ui.signin.SignInViewModel is injected at
          app.example.myapp.injection.module.ViewModelModule.bindSignInViewModel(signInViewModel)
      java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
          app.example.myapp.injection.ViewModelFactory(creators)
      app.example.myapp.injection.ViewModelFactory is injected at
          app.example.myapp.injection.module.ViewModelModule.bindViewModelFactory(factory)
      androidx.lifecycle.ViewModelProvider.Factory is injected at
          app.example.myapp.MainActivity.viewModelFactory
      app.example.myapp.MainActivity is injected at
          dagger.android.AndroidInjector.inject(T) [app.example.myapp.injection.AppComponent → app.example.myapp.injection.module.MainActivityModule_ContributeMainActivity.MainActivitySubcomponent]
  The following other entry points also depend on it:
      dagger.android.AndroidInjector.inject(T) [app.example.myapp.injection.AppComponent → app.example.myapp.injection.module.FragmentModule_ContributeMainFragment.MainFragmentSubcomponent]
      dagger.android.AndroidInjector.inject(T) [app.example.myapp.injection.AppComponent → app.example.myapp.injection.module.FragmentModule_ContributeSignInFragment.SignInFragmentSubcomponent]

正如您从错误中看到的那样,Dagger似乎能够从上下文跟踪到应用程序的根目录,但由于某种原因,我遇到了上述错误。

我做错了什么吗?谢谢

2 个答案:

答案 0 :(得分:0)

您正在尝试从添加到@Binds的模块中MainActivity AppComponent。那是行不通的,因为没有MainActivity(因为错误状态)。

@Module
abstract class MainActivityModule {
    @ContributesAndroidInjector
    abstract fun contributeMainActivity(): MainActivity

    // there is no MainActivity here (in AppComponent)
    @Binds
    abstract fun bindsMainActivityContext(mainActivity: MainActivity): @ActivityContext Context
}

您似乎想做的是将MainActivity绑定为Context in 在您的MainActivity子组件中,例如如下所示。您将需要第二个模块,然后将添加到子组件

@Singleton
@Component(
    modules = [
        AndroidInjectionModule::class,
        AppModule::class,
        ActivityModule::clas  // bind module with subcomponents instead, see next
    ]
)
interface AppComponent // ...

// Activity module that you can add to AppComponent with subcomponents
@Module
abstract class ActivityModule {

    // bind the module with the bindings here
    @ContributesAndroidInjector(modules = [MainActivityModule::class])
    abstract fun contributeMainActivity(): MainActivity

}

// now we bind it to the MainActivity Subcomponent _only_ and it will work
@Module
abstract class MainActivityModule {

    @Binds
    abstract fun bindsMainActivityContext(mainActivity: MainActivity): @ActivityContext Context
}

答案 1 :(得分:0)

根据该错误,匕首不知道如何提供此依赖项,或者您错过了依赖项中的@Inject批注,或者您可能忘记了提供带有@Provides批注的依赖项