I just started to learn Dagger and I wonder: Can it provide different implementations of the interface, depending on the request?
For example, I have an interface Api
and I have 2 implementations of this interface - TwitterApi
and FacebookApi
. Can I write something like the following?
@Provides
Api provideApi(ApiType type) {
switch (type){
case TWITTER_API:
return new TwitterApi();
case FACEBOOK_API:
return new FacebookApi();
}
}
Maybe @Named()
can help somehow?
This really depends on what you are trying to accomplish. You have 2 basic setups, whether you want to access your different implementations at once, or just want to supply one.
This is where you want to use a @Qualifier
, e.g. @Named
. It lets you define 2 qualified objects of the same type, so you could request / use both at the same time within the same module.
Here you just put a qualifier on both your implementations, and can provide & request both at the same time.
@Binds
@Qualifier("twitter")
Api provideApi(TwitterApi api);
And request with
@Inject @Qualifier("twitter") Api api;
In case that you have some ApiDependentThing
that takes one of your Api
implementations and you want to either provide TwitterApi
or FacebookApi
, you can just bind one of the implementations to your component. You can achieve this by using a @Component.Builder
, or @Binds
in a module, or some other way.
With this approach you would not use a qualifier, as you will only have one Api
on your graph that will be used within your component.
E.g. just bind one instance in your builder.
@Component
interface ApiComponent {
Api api();
@Component.Builder
interface Builder {
@BindsInstance Builder api(Api api);
ApiComponent build();
}
}