Dagger 2 for Android, Part III ー The @Qualifier and @Named Annotation

In this article, I will talk about how to use the @Qualifier
and @Named
annotation.
This is part of my Dagger 2 blog series:
- Dagger 2 for Android, Part I ー What is Dependency Injection?
- Dagger 2 for Android, Part II ー The Basic Usage
- Dagger 2 for Android, Part III ー The @Qualifier and @Named Annotation (you are here)
- Dagger 2 for Android, Part IV ー The @Scope Annotation
- Dagger 2 for Android, Part V ー @Inject for Constructor Injection
- Dagger 2 for Android, Part VI ー @Component.Builder and @BindsInstance
The code example used in this article will be written in Kotlin for Android development.
Pre-requiresite: Understanding basic usage of Dagger 2: @Inject
, Provides
, @Module
, and @Component
. Read Part II above if you haven't 😀
👆
Why do we need @Named?
In my previous post, I talked about how to use @Inject
to inject a field variable and how @Provides
fulfill the dependency to it.
There is a limitation though, we can only have a single @Provides
for this type.
Let's say we have Cat
class for example, that we will use in our MainActivity
But this time we want to use 2 cats: "Garfield"
and "HelloKitty"
:
So we have 2 @Provides
in the Module
:
But if you try to compile this code above, you will get this error:
That is because Dagger2
is confused which @Provides
should go into which @Inject
, because both are the same type Cat
. If one of them is of Dog
type, we will not have this problem.
@Named to the rescue!
To solve this we can use the annotation @Named
. By using this annotation, we can give the providers name:
Now Dagger2 is able to differentiate between Garfield
and Hello Kitty
. We can use it in the MainActivity
like this:
By annotaing @field:Named("HelloKitty")
on top of helloKitty
variable, Dagger2 is able to recognize that the provider will be provideHelloKitty()
. And the same for Garfield
.
That's the usage of @Named
🎉
What is @Named?
The @Named
annotation is good for identifying which provider to be used when we are trying to inject the dependency of the same type. Let's take a look at the @Named
annotation.
If you click into the definition of @Named
, you will see this:
The important annotation here to take note is @Qualifier
. This is actually an annotation that is used to define new annotation. It is also defined in the JSR330 standard (Doc is here). In fact, we can define our own qualifier
that will be similar to @Named
.
Optional reading 1
JSR330 is a set of Specification that is maintained by some committe members. So that any DI libraries which follows this specification will have the same interface. So if you look at ToothPick (another DI framework) for example, you can find@Qualifier
or@Inject
, etc.
Optional reading 2
As for@Documented
and@Retention(RUNTIME)
you can look them up separately if you are interested. It seems to be a convention to always add them when defining new qualifier. I've tried to remove them and Dagger2 works just fine.@Documented
is only used for documentation as the name indicated. As for@Retention(RUNTIME)
, this answer suggests that it is there due to legacy reason when older Reflection-based DI library (Roboguice) needed it, but Dagger2 doesn't actually need them.
Let's define our own qualifier that is similar to @Named
. Since all my code example is in Kotlin, let's rewrite @Named
in Kotlin. I will call it @NamedClone
Yay! Now we just defined our own @Named
annotation 🎉
This is how we use it:
The providers 👇
The the injectors 👇
The usage is exactly the same as @Named
!
Tweaking @NamedClone to use enum
By using @Qualifier
, it's pretty handy. However, if you noticed, we are relying on loose strings in the value of @Named
.
It's pretty error prone. ⚠️
Let's say we have "Red Apple"
in capital in the Module
.
And we have small case in the injecting side, "red apple"
Dagger2 will throw an error while compiling. 💀
This can be avoided if we change the String
into enum
.
By using this, you will get syntax error if you misspell it!
Wrapping up
Now that you know how to use @Named
and @Qualifier
, it is up to you on how to structure your code. Some people prefer to use @Named
since it is pre-defined, where some people prefer to always come up with @Qualifier
to make things cleaner.
*Remember not to waste too much time on deciding if there is no practical difference for your team! 😆
That's all for now, hope you learn a thing or two about qualifier annotation!

Next up: @Scope
. Stay tune!

Tan Jun Rong
Clap to support the author, help others find it, and make your opinion count.