【问题标题】:Dagger 2 Component with differently scoped modules具有不同范围模块的 Dagger 2 组件
【发布时间】:2018-01-03 21:46:44
【问题描述】:

上下文

我有两个 Dagger 2 模块:

  1. NetworkModule,具有 @Singleton 范围,提供 HTTP 客户端;
  2. ApiModule,具有自定义 @UserScope 范围,使用 HTTP 客户端为 Github 的 API 创建使用者。

然后,我创建一个 Dagger 2 组件,以提供 Retrofit 客户端。

NetworkModule.kt

@Module
class NetworkModule {
    @Provides
    @Singleton
    fun provideHttpClient(): OkHttpClient = OkHttpClient.Builder().build()
}

ApiModule.kt

@Module(includes = [NetworkModule::class])
class ApiModule(private val user: String) {

    @Provides
    @UserScope
    fun provideApi(httpClient: OkHttpClient): GithubApi = Retrofit.Builder()
            .baseUrl("https://api.github.com/")
            .client(httpClient)
            .build()
            .create(GithubApi::class.java)
}

ApiComponent.kt

@Component(modules = [ApiModule::class])
@UserScope
interface ApiComponent {
    fun inject(target: GithubRetriever)
}

问题

当我尝试构建应用程序时,如果我将@UserScope 范围添加到ApiComponent,则会收到以下错误消息:

e: ApiComponent.java:4: error: ApiComponent scoped with @UserScope may not reference bindings with different scopes:
e: 
e: @dagger.Component(modules = {ApiModule.class})
e: ^
e:       @org.jetbrains.annotations.NotNull @Singleton @Provides okhttp3.OkHttpClient NetworkModule.provideHttpClient()

如果我使用@Singleton 范围而不是@UserScope,也会发生同样的情况。

我应该如何声明ApiComponent 才能成功构建?

【问题讨论】:

    标签: java kotlin dagger-2


    【解决方案1】:

    单个模块不能引用两个范围;当您在 ApiModule (@Module(includes = [NetworkModule::class])) 中包含 NetworkModule 时,就会发生这种情况。

    但是,一个模块可以依赖使用不同范围的组件。

    @Component(modules = [NetworkModule::class])
    @Singleton
    interface NetworkComponent
    
    @Component(dependencies = [NetworkComponent::class], modules = [ApiModule::class])
    interface ApiComponent {
        fun inject(target: GithubRetriever)        
    }
    

    【讨论】:

    • 对不起,我错误地删除了我之前的评论。我在问我们是否需要为每个不同范围的模块创建不同的组件。感谢您的评论,我会将您的建议应用到我的代码中
    • 我创建了 NetworkComponent 并将其作为依赖项添加到 ApiComponent,正如您所建议的,但我仍然遇到同样的问题。我还尝试从ApiModule 的@Module 注释中删除includes = [NetworkModule::class],但在这种情况下,我收到另一个错误okhttp3.OkHttpClient cannot be provided without an @Inject constructor or from an @Provides-annotated method,因为ApiModule 无法“看到”@987654335 提供的OkHttpClient @
    • 不用担心。是的,每个范围至少应该有一个组件(多个组件可以具有相同的范围)(see Singletons and Scoped Bindings)。处理多个作用域的另一种方法是使用subcomponents,尽管我对子组件没有太多经验。
    • 嗯,您需要从ApiModule 中删除includes = [NetworkModule::class];但我不确定你为什么会收到这个新错误。您是否尝试从ApiModule 以外的其他地方引用OkHttpClient?尝试清理和重建您的项目。
    • 我通过将以下方法添加到NetworkComponent 来修复:fun httpClient(): OkHttpClient。通过这种方式,NetworkComponent 能够提供缺少的依赖项
    猜你喜欢
    • 2016-10-17
    • 2015-03-18
    • 2018-07-06
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多