简体   繁体   English

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

[英]Can't successfully provide dependency using Hilt

I'm new to Hilt.我是新来的希尔特。 I want to provide DataRepository for ViewModel .我想为ViewModel提供DataRepository My code in AppModule is:我在AppModule中的代码是:

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

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

And then I want to inject it to the constructor of ViewModel like private val dataRepository: DataRepository but I'm getting No value passed for parameter 'FeaturesApi' because FeaturesApi is dependecy of DataRepository .然后我想将它注入到 ViewModel 的构造函数中,例如private val dataRepository: DataRepository但我No value passed for parameter 'FeaturesApi'因为FeaturesApiDataRepository的依赖项。 What I want to do is just simply inject dependency without passing any values.我想要做的只是简单地注入依赖而不传递任何值。 How can I do it?我该怎么做?

Before using Hilt you should really try and understand how Dagger works.在使用Hilt之前,您应该真正尝试了解Dagger的工作原理。 Since, Hilt is built on top of Dagger!因为,Hilt 是建立在 Dagger 之上的!

So, Dagger requires you to provide a dependency graph.因此,Dagger 要求您提供依赖关系图。 Which means for each class which is injectable (using Dagger or Hilt) you must also provide a way for Dagger to create instances of its dependencies as well.这意味着对于每个可注入的class (使用 Dagger 或 Hilt),您还必须为 Dagger 提供一种方法来创建其依赖项的实例。

Considering the scenario posted in the OP.考虑到 OP 中发布的场景。 We have,我们有,

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

& &

class DataRepository(val featuresApi: FeaturesApi) {
}

As you have pointed out yourself featuresApi is a dependency of DataRepository and Dagger has no way of knowing how to create FeaturesApi object.正如您所指出的那样, featuresApiDataRepository的依赖项,而 Dagger 无法知道如何创建FeaturesApi object。

Now, Dagger provides three ways for you to tell it, how to create an instance of any class/type.现在,Dagger 提供了三种方法来告诉它,如何创建任何类/类型的实例。

  1. @Inject

You can use @Inject annotation on a constructor of a class defined in your own code to tell Dagger how to create that object.您可以在您自己的代码中定义的class的构造函数上使用@Inject注释来告诉 Dagger 如何创建该 object。 Like so:像这样:

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

Which will act similar to:这将类似于:

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

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

Note that there must only be a singular @Inject annotated constructor in any given class , since providing multiple @Inject annotated constructors will confuse Dagger on which constructor to use.请注意,在任何给定的class中只能有一个单一的@Inject注释构造函数,因为提供多个@Inject注释构造函数会混淆 Dagger 使用哪个构造函数。

  1. @Provides

You are already familiar with this annotation which can be used in a @Module annotated class .您已经熟悉此注解,它可以在@Module注解的class中使用。

This annotation is usually reserved to provide Dagger a way to create instances of classes/types which are not editable for you (Usually library classes or objects created by a library).这个注解通常保留给 Dagger 一种方法来创建你不可编辑的类/类型的实例(通常是库类或由库创建的对象)。 Which in this case will be, assuming your FeaturesApi object is created by Retrofit (which is the most popular networking library in Android).在这种情况下,假设您的FeaturesApi object 是由Retrofit (这是 Android 中最流行的网络库)创建的。

So, by rewriting your AppModule class a bit:因此,通过稍微重写您的AppModule

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

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

And now Dagger knows how to create a features FeaturesApi object.现在 Dagger 知道如何创建功能FeaturesApi object。

Note: At this point in your code you'd notice that you've now introduced a dependency for FeaturesApi ie Retrofit .注意:此时在您的代码中,您会注意到您现在已经引入了FeaturesApi的依赖项,即Retrofit So, now you must also provide a way for Dagger to know how to create Retrofit instance.所以,现在你还必须提供一种方法让 Dagger 知道如何创建Retrofit实例。 Otherwise Dagger will throw a similar error to No value passed for parameter 'Retrofit' .否则 Dagger 将抛出与No value passed for parameter 'Retrofit'类似的错误。

I'm leaving out the third way for you to figure out and study since that is not related to this question.我省略了第三种方式让您弄清楚和研究,因为这与这个问题无关。


Further Notes:进一步说明:

  • These annotations (with the exception of @InstallIn ) are in no way related to Hilt but are infact used by Dagger .这些注释( @InstallIn除外)与Hilt没有任何关系,但实际上由Dagger使用。
  • Also note that the better approach to access lower level objects (in this case DataRepository ) is through an interface .另请注意,访问较低级别对象(在本例中为DataRepository )的更好方法是通过interface

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

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