apollographql / apollo-kotlin

:rocket:  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
https://www.apollographql.com/docs/kotlin
MIT License
3.74k stars 653 forks source link

Unable to Inject ApolloClient with Dagger2 #1908

Closed praveeng145 closed 4 years ago

praveeng145 commented 4 years ago

Am unable to inject the ApolloClient object with Dagger2 even though I have the @Provides method. Here is my code snippet -

@Module
class GraphQLModule @Inject constructor() {

    companion object {
        private const val BASE_URL = "url"
    }

    @Provides
    @Singleton
    @Named("apolloGraphQlClient")
    fun providesApolloClient(
        graphQLFactory: ApolloClientFactory,
        okHttpClient: OkHttpClient
    ): ApolloClient {
        return ApolloClient
            .builder()
            .serverUrl(BASE_URL)
            .okHttpClient(okHttpClient)
            .normalizedCache(LruNormalizedCacheFactory(EvictionPolicy.builder().maxEntries(10).build())) // lru cache gets evicted after every 10 queries.
            .defaultHttpCachePolicy(HttpCachePolicy.CACHE_FIRST) // enable http cache
            .build()
    }
}

I added the above @Module to my main @Component and @Inject in my Fragment

This is the error message am getting -

[Updated the error message]

error: [Dagger/MissingBinding] com.apollographql.apollo.ApolloClient cannot be provided without an @Inject constructor or an @Provides-annotated method.
com.apollographql.apollo.ApolloClient is injected at
MyFragment.apolloClient
MyFragment is injected at

Am using the apollo-android version 1.2.2.

Am inject the ApolloClient as follows


MyFragment extends BaseFragment {

@Inject
ApolloClient apolloClient;

....

}
martinbonnin commented 4 years ago

That sounds like a dagger misconfiguration: The error message says you're injecting ApolloClient.Builder somewhere without providing it.

praveeng145 commented 4 years ago

err.. my bad I pasted the error when tried injecting ApolloClient.Builder - but bottomline it I see the similar error injecting ApolloClient as well.

I found that other classes in our codebase without public constructor gets injected successfully with @Provides-annotated methods, except ApolloClient. Not really sure what is wrong with the Dagger configuration.

martinbonnin commented 4 years ago

Maybe try removing @Named("apolloGraphQlClient") ?

praveeng145 commented 4 years ago

Yep.. already tried that. No luck. :(

tasomaniac commented 4 years ago

I would suggest to close the issue since there is nothing to be fixed in Apollo side. Still, happy to investigate and help this issue if you provide more information.

With an initial look, I was also suspecting the @Named annotation. If you use it, you need to use it in both places (@Provides and @Inject)

Also can you check if you use GraphQLModule appropriately? Where do you put that?

praveeng145 commented 4 years ago

Yes, I have setup GraphQLModule correctly. I tried injecting a different class which is having a public constructor and it worked. I tried removing @Named altogether but it didn't worked. I kept @Named at both both places @Provides and @Inject but no luck.

praveeng145 commented 4 years ago

Basically following the error message Dagger is unable to find the constructor that it can @Inject. However I have @Provides-annotated method, but it still it is unable to pick it up.

praveeng145 commented 4 years ago

I think I figured the problem - I "unintentionally" have a "protected" modifier before the apolloClient which caused the whole issue. Closing this issue.