Dagger2 找不到提供的实例
Dagger2 not finding provided instance
我在尝试将 Dagger 与多个组件一起使用时遇到了一些问题,我有以下内容(每个 class 在其自己的文件中):
范围:
@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 时,就会抛出错误。
将RepositoriesModule
纳入GetRandomBookUseCaseModule
@Module(includes = {RepositoriesModule.class})
class {
@Provides
@Singleton
fun provideGetRandomBookUseCase(booksRepository: BooksRepository) =
GetRandomBookUseCase(booksRepository)
}
并且组件应该是
@Component(
modules = [GetRandomBookUseCaseModule::class]
)
interface UseCasesComponent {
GetRandomBookUseCase getRandomBookUseCase();
}
我终于找到了问题所在:我没有在 UseCasesComponent 中返回 getRandomBookUseCase,最后我将 UseCasesComponent 更改为:
@Component(
modules = [GetRandomBookUseCaseModule::class]
)
@Singleton
interface UseCasesComponent {
val getRandomBookUseCase: GetRandomBookUseCase
}
和 BookReaderComponent 到:
@Component(
dependencies = [UseCasesComponent::class],
modules = [BookReaderModule::class]
)
@PrototypeScope
interface BookReaderFragmentComponent {
val bookReader: BookReader
}
然后在片段中我将其用作:
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)
bookReader = component.bookReader
...
}
...
}
非常感谢你的帮助,你真的帮了我很多,解决了我的问题。
我在尝试将 Dagger 与多个组件一起使用时遇到了一些问题,我有以下内容(每个 class 在其自己的文件中):
范围:
@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 时,就会抛出错误。
将RepositoriesModule
纳入GetRandomBookUseCaseModule
@Module(includes = {RepositoriesModule.class})
class {
@Provides
@Singleton
fun provideGetRandomBookUseCase(booksRepository: BooksRepository) =
GetRandomBookUseCase(booksRepository)
}
并且组件应该是
@Component(
modules = [GetRandomBookUseCaseModule::class]
)
interface UseCasesComponent {
GetRandomBookUseCase getRandomBookUseCase();
}
我终于找到了问题所在:我没有在 UseCasesComponent 中返回 getRandomBookUseCase,最后我将 UseCasesComponent 更改为:
@Component(
modules = [GetRandomBookUseCaseModule::class]
)
@Singleton
interface UseCasesComponent {
val getRandomBookUseCase: GetRandomBookUseCase
}
和 BookReaderComponent 到:
@Component(
dependencies = [UseCasesComponent::class],
modules = [BookReaderModule::class]
)
@PrototypeScope
interface BookReaderFragmentComponent {
val bookReader: BookReader
}
然后在片段中我将其用作:
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)
bookReader = component.bookReader
...
}
...
}
非常感谢你的帮助,你真的帮了我很多,解决了我的问题。