Search code examples
androiddagger-hilt

Hilt - How can I inject dependencies into adapter?


I am providing dependency in module:

@Provides
@Singleton
fun provideImageUtil(@ImageUrl imageUrl: String): ImageUtil = GlideImageUtil(imageUrl)

I am trying to inject it into RecyclerView adapter:

class MainAdapter(private val goods: ArrayList<GoodItem>) : RecyclerView.Adapter<MainAdapter.DataViewHolder>() {

    @Inject
    lateinit private var imageUtil: ImageUtil

I used to inject this way using Dagger:

object Injector {

    lateinit var appComponent: AppComponent

    fun initAppComponent(context: Context){

        if(context is Activity){
            throw IllegalStateException("pass an Application as an argument to avoid memory leaks")
        }

        appComponent = DaggerAppComponent.builder()
                .appModule(AppModule(context))
                .build()

    }

}

In adapter:

init {
    Injector.appComponent.inject(this)
}

How can I inject dependency into the adapter using Hilt? As I understood now "appComponent" is generated by Hilt. How can I access it?


Solution

  • First create EntryPoint in your custom class

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface MyEntryPoint {
        fun getImageUtil(): ImageUtil
    }
    

    It is simple interface with @EntryPoint annotation. Since your dependency (ImageUtil) is singleton you should use @InstallIn(SingletonComponent::class) annotation to declare component. Finally declare a method to get your dependency fun getImageUtil(): ImageUtil

    You can get your dependency in init block of your Adapter

    init {
        val myEntryPoint = EntryPointAccessors.fromApplication(context, MyEntryPoint::class.java)
        imageUtil = myEntryPoint.getImageUtil()
    }
    

    Full code

    class MainAdapter(
        context: Context,
        private val goods: ArrayList<GoodItem>
    ) : RecyclerView.Adapter<MainAdapter.DataViewHolder>() {
    
        var imageUtil: ImageUtil
    
        @EntryPoint
        @InstallIn(SingletonComponent::class)
        interface MyEntryPoint {
            fun getImageUtil(): ImageUtil
        }
    
        init {
            val myEntryPoint = EntryPointAccessors.fromApplication(context, MyEntryPoint::class.java)
            imageUtil = myEntryPoint.getImageUtil()
        }
    }
    

    See also https://developer.android.com/training/dependency-injection/hilt-android#not-supported