繁体   English   中英

无法使用 Hilt 成功提供依赖项

[英]Can't successfully provide dependency using 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的依赖项。 我想要做的只是简单地注入依赖而不传递任何值。 我该怎么做?

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

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

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

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

&

class DataRepository(val featuresApi: FeaturesApi) {
}

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

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

  1. @Inject

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

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 object 是由Retrofit (这是 Android 中最流行的网络库)创建的。

因此,通过稍微重写您的AppModule

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

    @Singleton
    @Provides
    fun provideFeaturesApi(retrofit: Retrofit): FeaturesApi {
        return retrofit.create(FeaturesApi::class.java)
    }
}

现在 Dagger 知道如何创建功能FeaturesApi object。

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

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


进一步说明:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM