使用 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
}
我有一个名为 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
}