使用 Hilt,如何注入没有上下文的 class?

Using Hilt, how to inject into a class that does not have a context?

我有一个名为 NetworkManager 的 class。由于它不是 Android 组件之一,我使用自定义入口点 NetworkManagerEntryPoint 和一个 fun 那个 returns NetworkClient 对象,这就是我想要的注射。

现在,要使用 Hilt 注入此 class 的实例,我相信我需要使用 EntryPointAccessors 中的一种辅助方法。但所有这些都需要引用 android 个组件。那么,我真的必须将 Context 之类的 android 组件传递给我的 class 才能使用 Hilt 注入对象吗?

class NetworkManager() {

    @InstallIn(SingletonComponent::class)
    @EntryPoint
    interface NetworkManagerEntryPoint {
        fun getNetworkClient(): NetworkClient
    }

    var defaultNetworkClient: NetworkClient = EntryPointAccessors.fromApplication(
        context, // Do I have to pass a context to this class to use Hilt?
        NetworkManagerEntryPoint::class.java
    ).getNetworkClient()

    fun <R : Any> executeRequest(
            request:Request<R>,
            networkClient: NetworkClient = defaultNetworkClient
    ): Response<R> {
        // Do some operation
    }
}

你好,也许你可以尝试我已经完成的这种方式,我遵循 mvvm 模式

我的 RetrofitApi

interface RetrofitApi {
@GET("endpoint")
suspend fun getApi():Response<RetrofitApiResponse>
}

我的网络模块

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule{

@Singleton
@Provides
fun provideApi(): RetrofitApi = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(RetrofitApi::class.java)

@Singleton
@Provides
fun provideRepository(retrofitApi:RetrofitApi) : MainRepository = 
DefualtMainRepository(retrofitApi)

}

并且这个模块被注入到我的存储库中

 class DefualtMainRepository @Inject constructor(
    val retrofitApi: RetrofitApi
):MainRepository {
override suspend fun getQuotes(): Resource<RetrofitApiResponse> {

        val response = retrofitApi.getApi()
        val result = response.body()
        if (response.successful){

        }
    }
   }

如果您有兴趣,我的 github 中有完整的项目,甚至还写了一篇中篇文章解释它,希望我的回答对您有所帮助 https://zaidzakir.medium.com/a-simple-android-app-using-mvvm-dagger-hilt-e9f45381f1bc

好的。 @Zaid Zakir 的回答告诉我,如果不是字段注入,我可以通过构造函数参数注入对象。所以,我的解决方案最终看起来像这样。

@Singleton
class NetworkManager @Inject constructor(
    var defaultNetworkClient: NetworkClient
) {
    fun <R : Any> executeRequest(
            request:Request<R>,
            networkClient: NetworkClient = defaultNetworkClient
    ): Response<R> {
        // Do some operation
    }
}

在另一个名为 NetworkClientModule 的 class 中,我有这个,

@Module
@InstallIn(SingletonComponent::class)
abstract class NetworkClientModule {

    @Binds @Singleton
    abstract fun bindDefaultNetworkClient(impl: DefaultNetworkClient): NetworkClient

}