Home > OS >  How does Hilt inject ViewModel parameters
How does Hilt inject ViewModel parameters

Time:11-01

In the documentation on Hilt, it shows this example of injecting a viewmodel into an activity:

@HiltViewModel
class ExampleViewModel @Inject constructor(
  private val savedStateHandle: SavedStateHandle,
  private val repository: ExampleRepository
) : ViewModel() {
  ...
}
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
  private val exampleViewModel: ExampleViewModel by viewModels()
  ...
}

But what if ExampleRepository itself has a constructor that requires parameters? How would the code in the activity be different? How do you tell Hilt what parameters to pass to Repository?

CodePudding user response:

there is multiple ways but I'll mention one I use for parameters that are from custom type like retrofit api service or OKHttp you need to provide it like below

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    fun provideOkHttpClient(
        @ApplicationContext context: Context,
        networkManager: NetworkManager,
        authenticator: AuthInterceptor,
        preferenceHelper: PreferenceHelper
    ): OkHttpClient {
        val httpLogging = HttpLoggingInterceptor()
        httpLogging.level = HttpLoggingInterceptor.Level.BODY
        val httpClient = OkHttpClient.Builder()
            .addInterceptor(authenticator)
            .connectTimeout(5, TimeUnit.MINUTES)
            .callTimeout(5, TimeUnit.MINUTES)
            .readTimeout(2, TimeUnit.MINUTES)
            .writeTimeout(2, TimeUnit.MINUTES)
        if (BuildConfig.BUILD_TYPE == Constants.STAGING_RELEASE)
            httpClient.addInterceptor(httpLogging)
        httpClient.addInterceptor(ChuckInterceptor(context))
        val httpCacheDirectory = File(context.cacheDir, "responses")
        val cacheSize: Long = 10 * 1024 * 1024
        val cache = Cache(httpCacheDirectory, cacheSize)
        httpClient.cache(cache)
        return httpClient.build()
    }
}
in this way when a parameter of type OkHttpClient is needed, this function will return it

CodePudding user response:

How do you tell the Hilt? With annotations. There is one REALLY good presentation from Jake Wharton on how Dependency injection works in Dagger2(on which Hilt is based on, so the idea is the same).

Most of what Dagger2/Hilt/DI is a Service Locator. Hilt is a compile-time thing so it goes over all of your files with those annotations and takes note of what is provided where and what needs what and generates files that do all of that logic "under the hood".

Even in your example:

@HiltViewModel
class ExampleViewModel @Inject constructor(
      private val savedStateHandle: SavedStateHandle,
      private val repository: ExampleRepository
) : ViewModel() {
  ...
}

You tell Hilt that ExampleViewModel is a @HiltViewModel. You also say that you want Hilt to create it for you - with @Inject - and you say that you want it to have two parameters savedStateHandle and repository. Now Hilt will try to locate in your files if there is a ExampleRepository with @Inject or if some module @Provides it explicitly.

class ExampleRepository @Inject constructor() {
  ...
}

or

@Module
@InstallIn(SingletonComponent::class)
object StorageModule {
    @Provides
    fun provideExampleRepository(): ExampleRepository = ExampleRepository()
}
  • Related