【问题标题】:Can't successfully provide dependency using Hilt无法使用 Hilt 成功提供依赖项
【发布时间】:2022-01-08 22:17:10
【问题描述】:

我是 Hilt 的新手。 我想为ViewModel 提供DataRepository。我在AppModule 中的代码是:

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

    @Singleton
    @Provides
    fun provideDataRepository(): DataRepository {
        return DataRepository()
    }
}

然后我想将它注入到 ViewModel 的构造函数中,例如private val dataRepository: DataRepository,但我得到了No value passed for parameter 'FeaturesApi',因为FeaturesApiDataRepository 的依赖项。我想要做的只是简单地注入依赖而不传递任何值。我该怎么做?

【问题讨论】:

    标签: android kotlin dagger-hilt


    【解决方案1】:

    在使用 Hilt 之前,您应该真正尝试了解 Dagger 的工作原理。因为,Hilt 是建立在 Dagger 之上的!

    因此,Dagger 要求您提供依赖关系图。这意味着对于每个可注入的class(使用 Dagger 或 Hilt),您还必须为 Dagger 提供一种方法来创建其依赖项的实例。

    考虑到 OP 中发布的场景。我们有,

    class DataViewModel(val dataRepository: DataRepository): ViewModel() {
    }
    

    &

    class DataRepository(val featuresApi: FeaturesApi) {
    }
    

    正如您自己指出的那样,featuresApiDataRepository 的依赖项,而 Dagger 无法知道如何创建 FeaturesApi 对象。

    现在,Dagger 提供了三种方法来告诉它,如何创建任何类/类型的实例。

    1. @Inject

    您可以在您自己的代码中定义的class 的构造函数上使用@Inject 注释来告诉Dagger 如何创建该对象。像这样:

    class DataRepository: @Inject constructor(
        private val featuresApi: FeaturesApi
    )
    

    这将类似于:

    @Module
    @InstallIn(SingletonComponent::class)
    object AppModule {
    
        @Singleton
        @Provides
        fun provideDataRepository(): DataRepository {
            return DataRepository()
        }
    }
    

    请注意,在任何给定的 class 中只能有一个单数的 @Inject 带注释的构造函数,因为提供多个 @Inject 带注释的构造函数会混淆 Dagger 使用哪个构造函数。

    1. @Provides

    您已经熟悉此注解,可在@Module 中使用注解class

    这个注解通常是为了给 Dagger 提供一种方法来创建对你来说不可编辑的类/类型的实例(通常是库类或由库创建的对象)。在这种情况下,假设您的 FeaturesApi 对象是由 Retrofit(这是 Android 中最流行的网络库)创建的。

    所以,通过重写你的 AppModule 类:

    @Module
    @InstallIn(SingletonComponent::class)
    object AppModule {
    
        @Singleton
        @Provides
        fun provideFeaturesApi(retrofit: Retrofit): FeaturesApi {
            return retrofit.create(FeaturesApi::class.java)
        }
    }
    

    现在 Dagger 知道如何创建特征 FeaturesApi 对象。

    注意:此时,在您的代码中,您会注意到您现在已经引入了 FeaturesApi 的依赖项,即 Retrofit。所以,现在你还必须提供一种方法让 Dagger 知道如何创建Retrofit 实例。否则 Dagger 会向No value passed for parameter 'Retrofit' 抛出类似的错误。

    我省略了第三种方式让你弄清楚和研究,因为这与这个问题无关。


    补充说明:

    • 这些注释(@InstallIn 除外)与 Hilt 没有任何关系,但实际上由 Dagger 使用。
    • 另请注意,访问较低级别对象(在本例中为 DataRepository)的更好方法是通过 interface

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      • 1970-01-01
      • 2020-09-14
      相关资源
      最近更新 更多