首页 > 解决方案 > Dagger2 没有找到提供的实例

问题描述

我在尝试将 Dagger 与多个组件一起使用时遇到了一些问题,我有以下内容(每个类都在自己的文件中):

范围:

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PrototypeScope

模块:

@Module(includes = [RepositoriesModule::class])
class GetRandomBookUseCaseModule {

    @Provides
    @Singleton
    fun provideGetRandomBookUseCase(booksRepository: BooksRepository) =
        GetRandomBookUseCase(booksRepository)
}


@Module
class RepositoriesModule {

    @Provides
    @Singleton
    fun providesBooksRepository(): BooksRepository = BooksRepositoryImpl()

    @Provides
    @Singleton
    fun providesPreferencesRepository(): PreferencesRepository = PreferencesRepositoryImpl()
}


@Module
class BookReaderModule(val ctx: Context) {

    @Provides
    @PrototypeScope
    fun provideBookReader(getRandomBookUseCase: GetRandomBookUseCase) =
        BookReader(ctx, getRandomBookUseCase)
}

组件:

@Component(
    modules = [GetRandomBookUseCaseModule::class]
)
interface UseCasesComponent {

}

@Component(
    dependencies = [UseCasesComponent::class],
    modules = [BookReaderModule::class]
)
@PrototypeScope
interface BookReaderFragmentComponent {

    fun inject(bookReaderFragment: BookReaderFragment)
}

然后,在 BookReaderFragment 我有以下内容:

class BookReaderFragment : Fragment() {
    @Inject lateinit var bookReader: BookReader
    val component: BookReaderFragmentComponent by lazy {
        DaggerBookReaderFragmentComponent
            .builder()
            .useCasesComponent(DaggerUseCasesComponent.create())
            .bookReaderModule(BookReaderModule(context!!))
            .build()
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        component.inject(this)
        ...
    }

    ...
}

然而,Dagger 未能做到:

error: GetRandomBookUseCase cannot be provided without an @Inject constructor or an @Provides-annotated method.

到底是怎么回事?为什么 Dagger 没有找到提供的方法?

非常感谢

更新:添加包含在 GetRandomBookUseCaseModule 中的 RepositoriesModule。经过这次更改,我意识到,虽然是错误消息,但问题与 BookReader 的注入方式有关。如果我以这种方式从 BookReaderFragment 中删除 @Injected :

class BookReaderFragment : Fragment() {
    lateinit var bookReader: BookReader
    val component: BookReaderFragmentComponent by lazy {
        DaggerBookReaderFragmentComponent
            .builder()
            .useCasesComponent(DaggerUseCasesComponent.create())
            .bookReaderModule(BookReaderModule(context!!))
            .build()
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        component.inject(this)
        ...
    }

    ...
}

然后没有错误,但是它在运行时不起作用,但是当设置了@Inject 时,就会抛出错误。

标签: androiddagger-2dagger

解决方案


纳入RepositoriesModule_GetRandomBookUseCaseModule

@Module(includes = {RepositoriesModule.class})
class {

    @Provides
    @Singleton
    fun provideGetRandomBookUseCase(booksRepository: BooksRepository) =
        GetRandomBookUseCase(booksRepository)
}

组件应该是

@Component(
    modules = [GetRandomBookUseCaseModule::class]
)
interface UseCasesComponent {
    GetRandomBookUseCase getRandomBookUseCase();
}

推荐阅读