Home > Net >  Kotlin Hilt: Class cannot be provided without an @Provides-annotated method when injecting into an
Kotlin Hilt: Class cannot be provided without an @Provides-annotated method when injecting into an

Time:08-30

I was trying to look for similar posts in SO before posting, but most of them talk about retrofit, and my question is about injecting a dependency (Service, Repository or whatever) into an object using @EntryPoint.

I have an object like this:

object FreddieMercuryYouAreTheOne {

    lateinit var exception: ExceptionHandler

    fun init(appContext: Context) {
        setDependencies(appContext)
        DoOtherInitStuff...
    }

    private fun setDependencies(appContext: Context){
        val exh = EntryPointAccessors.fromApplication(appContext, Dependencies.ProvideExceptionHandler::class.java)
        this.exception = exh.exceptionHandler()
    }

    /*
    * THIS IS JUST AN ABSURD EXAMPLE
    * */
    private fun DoWhatever(cryptKey16CharStr: String, cryptInitializationVector16CharStr: String) {
        try {
            doWhatever
        }catch(ex: Exception){
            exception.logException(ex)
        }
    }
}

And then I have the class where I set the dependencies:

@Module
@InstallIn(SingletonComponent::class)
class Dependencies {

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface ProvideExceptionHandler {
        fun exceptionHandler(): ExceptionHandler
    }
}

And when building, what I get is the following error:

error: [Dagger/MissingBinding] exception.ExceptionHandler cannot be provided without an @Provides-annotated method.

Well, if I modify my dependencies module as follows:

@Module
@InstallIn(SingletonComponent::class)
class Dependencies {

    @Provides
    @Singleton
    fun bindsExceptionHandler(): ExceptionHandler {
        return ExceptionHandler
    }

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface ProvideExceptionHandler {
        fun exceptionHandler(): ExceptionHandler
    }
}

Not only build, but it works, and ExceptionHandler is correctly injected in FreddieMercuryYouAreTheOne object, so, as you see, what I have is not exactly an issue, but wondering to know why I need two "providers" to be able to inject a dependency into an object, lets say, why is not enough with interface ProvideExceptionHandler (as Google documentation mentions).

I ask this because I have many class objects across my app, and most of them have dependencies, and so this way I'll have to create two providers for each dependency. Am I doing something wrong?

CodePudding user response:

Entry Points used for field injection for un-supported classes by Hilt like a custom class or content provider.

in your case since you have object FreddieMercuryYouAreTheOne thats can't has a constructer . yeah you need :

1- to Provide the object(instance) you want in your case:

 @Provides
    @Singleton
    fun bindsExceptionHandler(): ExceptionHandler {
        return ExceptionHandler
    }

2- and then say hey!! ,i need field injection in my custom class then you should use :

 @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface ProvideExceptionHandler {
        fun exceptionHandler(): ExceptionHandler
    }

if you have a normal class you just need to provide the object(just point #1). and then inject it in the constructer.

as i say @EntryPoint for un-supported classes field injection just.

Hint the recommended is constructer-injection over field injection

PLUS: ExceptionHandler and most of dependencies should be injected into ViewModel

  • Related