我首先在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
答案 0 :(得分:1)
请注意,iosched example MainActivity.kt:116会注入MainActivity ViewModel :
private lateinit var viewModel: MainActivityViewModel
虽然您已注入MainActivity 模块:
@Inject lateinit var viewModel: MainActivityModule
一些注意事项:
模块用于配置Dagger:您永远不需要从ViewModels,Activity,View或其他类中注入或引用 modules 。如果您拥有的模块不是接口或抽象(开放)类,并且没有公共的无参数构造函数,则只能在 与所有模块实例进行交互。
尽管事实上您几乎永远都不应在图中注入模块,但Dagger会允许您这样做,并且仅当绑定到您的模块中图形。这就是您应该阅读错误消息的方式:“没有@Provides注释的方法,将无法提供com.example.app.di.MainActivityModule”;由于您已经通过@Inject
请求了MainActivityModule,而Dagger不知道如何提供它,因此它会抛出此编译时异常。
请注意,iosched的MainActivity.kt不会将MainActivityViewModel标记为可注入;就像您在此处发布的代码中所做的那样,它将手动on line 136创建实例。您应该构造实例,或者Dagger应该构造实例,但不能两者都构造。 (Dagger有时在填充现有实例上的@Inject
字段时很有用,但您无需在此处执行此操作。)因此,在任何情况下,都可以删除@Inject
批注,Dagger将不再为此担心。