如果没有 @Provides-annotated 方法,则无法提供 MainActivityModule

MainActivityModule cannot be provided without an @Provides-annotated method

我首先在 android 中使用了 dagger2,我尝试使用与 google/iosched 相同的结构来反映我的项目。但是当我在下面编译这个简单的项目时,它报告 MainActivityModule cannot be used in it.

// MainApplication.kt

class MainApplication : DaggerApplication() {

    ...

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.factory().create(this)
    }

    ...
}


// AppComponent.kt

@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class,
        AppModule::class,
        ActivityBindingModule::class,
        ViewModelModule::class
    ]
)
interface AppComponent : AndroidInjector<MainApplication> {
    @Component.Factory
    interface Factory {
        fun create(@BindsInstance application: MainApplication): AppComponent
    }
}


// ActivityBindingModule.kt

@Module
@Suppress("UNUSED")
abstract class ActivityBindingModule {

    @ActivityScoped
    @ContributesAndroidInjector(
        modules = [
            // activity
            MainActivityModule::class
        ]
    )
    internal abstract fun mainActivity(): MainActivity
}


// MainActivity.kt

class MainActivity : DaggerAppCompatActivity() {

    @Inject lateinit var viewModelFactory: ViewModelProvider.Factory
    @Inject lateinit var viewModel: MainActivityModule

    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(R.style.AppTheme)
        super.onCreate(savedInstanceState)

        viewModel = viewModelProvider(viewModelFactory)
    }
    ...
}


// MainActivityModule.kt

@Module
@Suppress("UNUSED")
abstract class MainActivityModule {

    @Binds
    @IntoMap
    @ViewModelKey(MainActivityViewModel::class)
    internal abstract fun bindViewModel(viewModel: MainActivityViewModel): ViewModel
}


// MainActivityViewModel.kt

class MainActivityViewModel @Inject constructor(

) : ViewModel() {

}

错误信息如下。

[Dagger/MissingBinding] com.example.app.di.MainActivityModule cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.app.MainApplication> {
                ^
      com.example.app.di.MainActivityModule is injected at
          com.example.app.ui.MainActivity.viewModel
      com.example.app.ui.MainActivity is injected at

注意 iosched example MainActivity.kt:116 注入 MainActivityViewModel:

private lateinit var viewModel: MainActivityViewModel

当您注入 MainActivityModule 时:

@Inject lateinit var viewModel: MainActivityModule

这里有几点说明:

  1. 模块用于配置 Dagger:您永远不需要从 ViewModel、Activity、View 或其他 [=51= 中注入或引用 modules ]是的。您应该只与 Module 实例交互 如果 您有一个不是接口或抽象(开放)的 Module class,并且没有 public 无参数构造函数。

  2. 尽管您几乎不应该在图表中注入模块,但 Dagger 会允许您这样做当且仅当 它们绑定在您的图表中。这就是您应该如何阅读错误消息:"com.example.app.di.MainActivityModule cannot be provided without an @Provides-annotated method";由于您已通过 @Inject 请求 MainActivityModule,而 Dagger 不知道如何提供,因此它会抛出此编译时异常。

  3. 请注意,iosched 的 MainActivity.kt 不会将 MainActivityViewModel 标记为可注入;它像您在此处发布的代码中一样手动创建实例 on line 136。要么你应该构建实例,要么 Dagger 应该构建实例,但不能同时构建。 (Dagger 偶尔可用于在现有实例上填充 @Inject 字段,但您不会在此处执行此操作。)因此在任何情况下您都可以删除 @Inject 注释,Dagger 将不再担心它。