没有@Provides注释的方法,无法提供MainActivityModule

时间:2020-05-11 08:38:40

标签: android dagger-2

我首先在android中使用dagger2,然后尝试使用与google/iosched相同的结构来反映我的项目。但是,当我在下面编译此简单项目时,它报告MainActivityModule无法在其中使用。

// 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

1 个答案:

答案 0 :(得分:1)

请注意,iosched example MainActivity.kt:116会注入MainActivity ViewModel

private lateinit var viewModel: MainActivityViewModel

虽然您已注入MainActivity 模块

@Inject lateinit var viewModel: MainActivityModule

一些注意事项:

  1. 模块用于配置Dagger:您永远不需要从ViewModels,Activity,View或其他类中注入或引用 modules 。如果您拥有的模块不是接口或抽象(开放)类,并且没有公共的无参数构造函数,则只能在 与所有模块实例进行交互。

  2. 尽管事实上您几乎永远都不应在图中注入模块,但Dagger会允许您这样做,并且仅当绑定到您的模块中图形。这就是您应该阅读错误消息的方式:“没有@Provides注释的方法,将无法提供com.example.app.di.MainActivityModule”;由于您已经通过@Inject请求了MainActivityModule,而Dagger不知道如何提供它,因此它会抛出此编译时异常。

  3. 请注意,iosched的MainActivity.kt不会将MainActivityViewModel标记为可注入;就像您在此处发布的代码中所做的那样,它将手动on line 136创建实例。您应该构造实例,或者Dagger应该构造实例,但不能两者都构造。 (Dagger有时在填充现有实例上的@Inject字段时很有用,但您无需在此处执行此操作。)因此,在任何情况下,都可以删除@Inject批注,Dagger将不再为此担心。