如何在Hilt中生成相同类型的对象?

pnk*_*nkj 12 android kotlin dagger-2 android-jetpack dagger-hilt

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Singleton
    @Provides
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("http://example.com/")
            .client(okHttpClient)
            .build()
    }

    @Singleton
    @Provides
    fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("http:/my.com/")
            .client(okHttpClient)
            .build()
    }
}
Run Code Online (Sandbox Code Playgroud)

他们的区别仅在于baseUrl


我试图通过使用来解决这个问题@Qualifier

interface RetrofitQualifier {
    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    annotation class Retrofit

    @Qualifier
    @Retention(AnnotationRetention.BINARY)
    annotation class MyRetrofit
}
Run Code Online (Sandbox Code Playgroud)
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Singleton
    @Provides
    @RetrofitQualifier.Retrofit
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("http://example.com/")
            .client(okHttpClient)
            .build()
    }

    @Singleton
    @Provides
    @RetrofitQualifier.MyRetrofit
    fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("http:/my.com/")
            .client(okHttpClient)
            .build()
    }
}
Run Code Online (Sandbox Code Playgroud)

@RetrofitQualifier.MyRetrofit我在课堂上使用它:

class MyRepository @Inject constructor(
    application: Application
)  {

    ...    

    @Inject
    @RetrofitQualifier.MyRetrofit
    lateinit var  retrofit:Retrofit


    private val service: Service = retrofit.create(Service::class.java)

    ...

    }
Run Code Online (Sandbox Code Playgroud)

然而我失败了,日志是

kotlin.UninitializedPropertyAccessException: lateinit property retrofit has not been initialized
Run Code Online (Sandbox Code Playgroud)

我应该怎么办?也许使用@Named?我不知道...

Ski*_*ᴉʞS 26

例如Qualifier,您可以将其添加到您拥有提供商的同一文件中,甚至创建一个RetrofitQualifier.kt文件并将其添加到其中。

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitOne

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class RetrofitTwo
Run Code Online (Sandbox Code Playgroud)

还有@Provides

@Singleton
@Provides
@RetrofitOne
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
    return Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl("http://example.com/")
        .client(okHttpClient)
        .build()
}

@Singleton
@Provides
@RetrofitTwo
fun provideMyRetrofit(okHttpClient: OkHttpClient): Retrofit {
    return Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl("http:/my.com/")
        .client(okHttpClient)
        .build()
}
Run Code Online (Sandbox Code Playgroud)

然后Repository你可以使用两个选项进行注入

现场注入

// At field injection.
@AndroidEntryPoint
class MyRepository @Inject constructor(...) {

  @RetrofitOne
  @Inject lateinit var retrofit: Retrofit
}
Run Code Online (Sandbox Code Playgroud)

作为依赖注入构造函数类

// As a dependency of a constructor-injected class.
class MyRepository @Inject constructor(
  @RetrofitTwo private val retrofit: Retrofit
) : ...

Run Code Online (Sandbox Code Playgroud)

但问题是,也许您安装在另一个模块中,您的存储库不具有可见性。

关于@Named您仍然可以使用它,但根据文档建议使用Qualifier