Search code examples
javaandroidkotlindagger-2

Problem Dagger Cannot be provided without an @Provides-annotated method, When I use @Named annotation


I am facing a problem when I put the @Named annotation in the AppModule and here is my code, The problem appears only when I add the @Named annotation to both the 'AppModule' and the 'IdentityRepository', but when I remove it from both everything is fine

Note that I have to use @Named because I want to create a second function with the same DataType in the same Module

@Module
object AppModule {
...

    @Provides
    @JvmStatic
    @Singleton
    @Named("NOT_AUTH_IDENTITY_SERVICE")
    fun provideIdentityService(retrofit: Retrofit): IdentityService =
        retrofit.create(IdentityService::class.java)
}

and when I use it the IdentityRepository

class IdentityRepository @Inject constructor() {

    @Inject
    @Named("NOT_AUTH_IDENTITY_SERVICE")
    lateinit var identityService: IdentityService
...
}

I am facing this error

error: [Dagger/MissingBinding] solutions IdentityService cannot be provided without an @Provides-annotated method. public abstract interface AppComponent extends dagger.android.AndroidInjector { ...


Solution

  • Following the documentation:

    When you're annotating a property or a primary constructor parameter, there are multiple Java elements which are generated from the corresponding Kotlin element, and therefore multiple possible locations for the annotation in the generated Java bytecode. To specify how exactly the annotation should be generated.

    when using Named providers with Kotlin you have to explicitly annotate the field with the @field annotation:

    class IdentityRepository @Inject constructor() {
    
        @Inject
        @field:Named("NOT_AUTH_IDENTITY_SERVICE")
        lateinit var identityService: IdentityService
    ...
    }
    

    Or you could just move the property to a constructor, since you are also using constructor injection:

    class IdentityRepository @Inject constructor(
        @Named("NOT_AUTH_IDENTITY_SERVICE") val identityService: IdentityService
    ) {
    ...
    }