没有@Provides注释的方法Dagger / MissingBinding不能提供

时间:2020-01-30 12:06:19

标签: android kotlin dagger-2 android-mvp

无法将演示者注入活动

BookDashboard->活动

class BookDashboard : AppCompatActivity(),BookDashboardContract.MvpView{

    @Inject
    lateinit var presenter: BookDashboardContract.Presenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        presenter.fetchedBooks() 
        // if I pass no parameter to BookPresenter than UninitializedPropertyAccessException: lateinit property presenter has not been initialized
    }

    override fun displayBooks() {
        Toast.makeText(this,"Books Displayed",Toast.LENGTH_LONG).show()
    }

    override fun showProgress() {}
    override fun hideProgress() {}
}

BookDashboardContract

interface BookDashboardContract {

    interface MvpView{
        fun displayBooks()
        fun showProgress()
        fun hideProgress()
    }

    interface Presenter{
        fun fetchedBooks()
    }
}

BookDashboardPresenter 如果我没有传递任何参数到下面的构造函数应用程序将运行,但仍然没有演示者 并在 BookDashboard -> Activity __中的presenter.fetchBooks()处崩溃了。__查看该代码中的注释

class BookDashboardPresenter @Inject constructor(val viewContract:BookDashboardContract.MvpView) : BookDashboardContract.Presenter{

    val bookInteractor = BookInteractor(this)

    override fun fetchedBooks() {
        bookInteractor.fetchDataFromServer()
        viewContract.displayBooks()
    }
}

ActivityBuilder

@Module
abstract class ActivityBuilder {

    @ContributesAndroidInjector(modules = {BookDashboardModule.class})
    @ActivityScope
    public abstract BookDashboard bindBookDashboard();
}

BookDashboardModule

@Module
abstract class BookDashboardModule {

    @Binds
    @ActivityScope
    abstract fun presenter(presenter: BookDashboardPresenter): BookDashboardContract.Presenter
}

我使用的第二种方法。但仍然没有主持人

 @Module
 class BookDashboardModule(val mvpView: BookDashboardContract.MvpView) {

    @Provides
    @ActivityScope
    fun providesCategoryView(): BookDashboardContract.MvpView {
        return this.mvpView
    }

    @Provides
    @ActivityScope
    fun provideBookPresenter(): BookDashboardPresenter {
        return BookDashboardPresenter(mvpView)
    }
}

@ Subcomponent.Factory方法缺少必需模块或subcomp的参数

@Module(subcomponents = ActivityBuilder_BindBookDashboard.BookDashboardSubcomponent.class)
public abstract class ActivityBuilder_BindBookDashboard {
  private ActivityBuilder_BindBookDashboard() {}

  @Binds
  @IntoMap
  @ClassKey(BookDashboard.class)
  abstract AndroidInjector.Factory<?> bindAndroidInjectorFactory(
      BookDashboardSubcomponent.Factory builder);

  @Subcomponent(modules = BookDashboardModule.class)
  @ActivityScope
  public interface BookDashboardSubcomponent extends AndroidInjector<BookDashboard> {
    @Subcomponent.Factory
    interface Factory extends AndroidInjector.Factory<BookDashboard> {}
  }
}

修改

作为Onik注释,我已用DaggerAppCompatActivity替换了AppCompatActivity,但仍然无法注入演示者

没有@ Provides-注释,就无法提供MvpView

/Users/geek/StudioProjects/MyApplication/app/build/tmp/kapt3/stubs/debug/quiz/mania/trivia/mcq/question/di/AppComponent.java:8: error: [Dagger/MissingBinding] quiz.mania.trivia.mcq.question.booksmvp.contract.BookDashboardContract.MvpView cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector<quiz.mania.trivia.mcq.question.App> {
                ^
      quiz.mania.trivia.mcq.question.booksmvp.contract.BookDashboardContract.MvpView is injected at
          quiz.mania.trivia.mcq.question.booksmvp.presenter.BookDashboardPresenter(viewContract)
      quiz.mania.trivia.mcq.question.booksmvp.presenter.BookDashboardPresenter is injected at
          quiz.mania.trivia.mcq.question.di.BookDashboardModule.presenter(presenter)
      quiz.mania.trivia.mcq.question.booksmvp.contract.BookDashboardContract.Presenter is injected at
          quiz.mania.trivia.mcq.question.booksmvp.BookDashboard.presenter
      quiz.mania.trivia.mcq.question.booksmvp.BookDashboard is injected at
          dagger.android.AndroidInjector.inject(T) [quiz.mania.trivia.mcq.question.di.AppComponent → quiz.mania.trivia.mcq.question.di.ActivityBuilder_BindBookDashboard.BookDashboardSubcomponent]

AppComponent

@Component(
    modules = [
        AndroidInjectionModule::class, // why it is necessary to use this class for injecting purpose
        AppModule::class,
        ActivityBuilder::class
    ]
)
@Singleton
interface AppComponent : AndroidInjector<App> {

    @Component.Builder
    interface Builder {

        fun addContext(@BindsInstance context: Context): Builder

        fun build(): AppComponent
    }
}

App.kt

class App : DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().addContext(this).build()
    }
}

1 个答案:

答案 0 :(得分:1)

我认为依赖关系图有些混乱。请按如下所示更改您的代码,然后重试:

@Module
 class BookDashboardModule {

    @Provides
    @ActivityScope
    fun provideBookPresenter(view: BookDashboard): BookDashboardContract.Presenter = BookDashboardPresenter(view)
}

////////

@Module
abstract class ActivityBuilder {

    @ContributesAndroidInjector(modules = {BookDashboardModule.class})
    @ActivityScope
    abstract fun bind(): BookDashboard
}

/////////

class BookDashboardPresenter @Inject constructor(val view: BookDashboardContract.MvpView) : BookDashboardContract.Presenter{

    val bookInteractor = BookInteractor(this)

    override fun fetchedBooks() {
        bookInteractor.fetchDataFromServer()
        view.displayBooks()
    }
}