1

I am using an AuthenticationRequest object from an external module in my app module. I supply this object as a dependency to my AccountRepository. This is how I have defined my dependency in the app module.

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

@Provides
@Singleton
fun provideRepository(
    authenticationRequest: AuthenticationRequest,
    accountDao: AccountDao
) = AccountRepository(authenticationRequestFactory, accountDao)

}

The constructor for AuthenticationRequest in the external module:

class AuthenticationRequest(
   api: AuthenticationApi,
   apiError : ApiError =  ApiErrorImpl()
) : Request<AuthenticationApi>(api, apiError)

And the AccountRepository:

class AccountRepository @Inject constructor(
   private val authenticationRequestFactory: AuthenticationRequestFactory,
   private val accountDao: AccountDao
) {....}

But I am getting the following error message: Dagger/MissingBinding] com.external.auth.AuthenticationRequest cannot be provided without an @Inject constructor or an @Provides-annotated method.

How do I correctly inject the AuthenticationRequest object? Note that the module where this object is defined does not use Dagger-Hilt. It uses Dagger-2 though. Any pointers would be great.

Note: Project Structure is

|-- :app
 -- :external module
GraSim
  • 3,830
  • 1
  • 29
  • 35

1 Answers1

3

Dagger/Hilt can only create classes that have the @Inject constructor. As you say, AuthenticationRequest class is not set up like this.

You need to add a @Provides method to let Dagger know how to create the class:


@InstallIn(SingletonComponent::class)
@Module
object ApplicationModule {
    @Provides
    @Singleton
    fun provideAuthenticationRequest(
        someDependency: SomeDependency,
        anotherOne: AnotherOne,
    ): AuthenticationRequest {
        return AuthenticationRequest(
            someDependency,
            anotherOne
        )
    }

    @Provides
    @Singleton
    fun provideSomeDependency(): SomeDependency {
        return SomeDependency()
    }

    @Provides
    @Singleton
    fun provideAnotherOne(
        evenMoreDependency: EvenMoreDependency
    ): AnotherOne {
        return AnotherOne(evenMoreDependency)
    }

    @Provides
    @Singleton
    fun provideEvenMoreDependency(): EvenMoreDependency {
        return EvenMoreDependency()
    }

}

As @bapness says, this should be an object. You only need to make a (abstract) class when creating a @Binds method, as Hilt is going to make an implementation. But this won't be needed in this case.

As for if it should be all in one component - That's up to you really. I'd say if you're not sure then put them all in one object, it's not a big deal to migrate them into their own files at a later date.

More info: https://dagger.dev/dev-guide/ under "Satisfying Dependencies"

Gilles Braun
  • 119
  • 1
  • 6
  • This will not work. The `AuthenticationRequest` object has further dependencies of its own, all the examples I have found for using Hilt with Third Party Dependencies do not show examples with any dependencies. – GraSim Nov 29 '21 at 10:42
  • I think @gilles is right. And you can split `AuthentifcationRequest` provide function into a dedicated file in your `:external_module`. Also, as mention in the follow link, you should declare `object` instead of `class` for your Hilt `@Module`. https://developer.android.com/training/dependency-injection/hilt-android#inject-provides – BapNesS Nov 29 '21 at 19:40
  • @GraSim you would have to create more provides-methods for all required dependencies in the chain, until there is no dependency left. – Gilles Braun Dec 01 '21 at 11:02
  • @GillesBraun Do I provide the dependencies all in the same class? Does it need to declared as object or class? If you can provide a complete answer that works , I will upvote so others coming across this can see the solution. – GraSim Dec 01 '21 at 12:03
  • 1
    @GraSim I updated the answer with a more complete sample and additional information – Gilles Braun Dec 01 '21 at 16:54