Dagger:如果没有 @Inject 构造函数或 @Provides-annotated 方法,则无法提供
Dagger: cannot be provided without an @Inject constructor or an @Provides-annotated method
我正在尝试将我的 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 似乎能够从上下文跟踪到应用程序的根目录,但由于某种原因我得到了上述错误。
我做错了什么吗?谢谢
您正在尝试从您添加到 AppComponent
的模块中 @Binds
MainActivity
。那行不通,因为没有 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
}
根据报错,dagger 不知道如何提供这个依赖,要么你错过了依赖中的@Inject 注解,要么你可能忘记了用@Provides 注解提供依赖
我正在尝试将我的 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 似乎能够从上下文跟踪到应用程序的根目录,但由于某种原因我得到了上述错误。
我做错了什么吗?谢谢
您正在尝试从您添加到 AppComponent
的模块中 @Binds
MainActivity
。那行不通,因为没有 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
}
根据报错,dagger 不知道如何提供这个依赖,要么你错过了依赖中的@Inject 注解,要么你可能忘记了用@Provides 注解提供依赖