Dagger2 where inject @Named @Provides in dependent module?
Asked Answered
C

4

9

I use dagger2 demo by https://guides.codepath.com/android/Dependency-Injection-with-Dagger-2. I want to use cached and non_cached retrofit call. I create in NetModule.java

@Provides @Named("cached")
@Singleton
OkHttpClient provideOkHttpClient(Cache cache) {
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .cache(cache)
            .build();
    return okHttpClient;
}

@Provides @Named("non_cached")
@Singleton
OkHttpClient provideOkHttpClientNonCached() {
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .build();
    return okHttpClient;
}

GitHubModule.java is dependent on NetModule.java. my GitHubComponent.java

@UserScope
@Component(dependencies = NetComponent.class, modules = GitHubModule.class)
public interface GitHubComponent {
void inject(DemoDaggerActivity activity);
}

my NetComponent.java

@Singleton
@Component(modules={ApplicationModule.class, NetModule.class})
public interface NetComponent {
// downstream components need these exposed
Retrofit retrofit();
OkHttpClient okHttpClient();
SharedPreferences sharedPreferences();
}

In my DemoDaggerActivity.java I inject retrofit:

@Inject @Named("cached")
OkHttpClient mOkHttpClient;

@Inject
Retrofit mRetrofit;

After rebuild project I get error:

enter image description here

Where can I tell to dagger, that i want to use cached or non_cached retrofit?

Charitacharitable answered 13/7, 2017 at 12:10 Comment(0)
B
15

Your Retrofit provider should use @Named annotation for OkHttpClient, for example:

@Provides
@Singleton
public Retrofit provideRetrofit(@Named("cached") OkHttpClient okHttpClient)
{
    return new Retrofit.Builder()
            .baseUrl("...")
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build();
}
Boneblack answered 13/7, 2017 at 12:36 Comment(0)
H
4

If you are using kotlin, the correct way to inject named is next:

@field:[Inject Named("api1")].

Source: https://medium.com/@WindRider/correct-usage-of-dagger-2-named-annotation-in-kotlin-8ab17ced6928

Harlot answered 12/8, 2019 at 11:53 Comment(0)
E
3

You have two methods with same name: provideOkHttpClient(). Rename one of them, make them distinct.

Earhart answered 13/7, 2017 at 12:12 Comment(0)
D
0

For Kotlin, use:

@Inject
@field:Named("cached")
lateinit var mOkHttpClient: OkHttpClient

Focus on the @Named annotation, which is specificed using @field annotation use-site target from Kotlin. Since, no @Target is specified in @Named annotation source code in Dagger for older versions, we need to tell the Kotlin compiler where to apply this annotation, hence the @field use-site annotation target. A FIELD @Target is specified for @Inject annotation in the source code, hence we do not need to specify a target for it explicitly and the compiler picks the correct target automatically

Also, when you have multiple annotations, they can be combined in an array-like syntax as:

@field:[Inject Named("cached")]
lateinit var mOkHttpClient: OkHttpClient

For a more thorough understanding, refer this.

Dittman answered 12/8, 2023 at 14:34 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.