같은 타입의 Provider가 있을때 구분
앞서 Provider을 이용해 주입(Inject)가 되는 것을 보았다. 하지만, Provider만 사용하여 주입하는 것에는 문제점이 있다.
바로 Provider에서 제공(Provide)하는 인스턴스의 타입이 같을 때 어떤 인스턴스를 주입해야 하는지 모른다는 것이다.
예를 들어 아래와 같은 Module이 있다고 해보자.
@Module
class PersonModule {
@Provides
fun providesStudentName(): String = "StudentA"
@Provides
fun providesTeacherName(): String = "TeacherB"
}
이 모듈에서 제공하는 두가지 Provider의 반환 타입은 모두 String이다. 이 때 String 값을 아래 Student Class의 인스턴스에서 주입받고자 할 경우 어떤 Provider에서 주입 받아야 하는지 알 수 없다.
class Student() {
@Inject
lateinit var name: String
}
이를 그림으로 표현하면 다음과 같다.

Person Module 내에 같은 타입을 반환하는 Provider가 있어 주입 시 어떤 Provider을 주입시켜야 하는지 모르는 것이다.
@Named Annotation을 이용한 같은 타입 Provider 구분
이를 해결하기 위해서는 @Named Annotation을 활용한다. @Named Annotation은 같은 타입 클래스의 인스턴스를 제공하는 Provider가 두 개 이상 있을 때 그 둘을 구분해주는 역할을 한다.
제공하는 쪽(Provider)과 주입 당하는쪽(Inject) 모두에 @Named Annotation을 사용해야 구분이 되므로 둘 모두에다가 @Named Annotation을 붙여야 구분이 주입이 가능해진다.
위의 <그림1>을 <그림2>와 같이 바꾸면 Student에는 Student 이름의 주입이 가능해진다.

제공(Provider)하는 쪽의 fun과 주입받은 Student 에 모두 @Named 를 붙임으로써 Student가 어떤 Provider로부터 name 프로퍼티를 주입 받아야 하는지가 명확해졌다.
예제4에서 이에 대해 다루도록 한다. 먼저 예제4의 파일 구조는 다음과 같다.
예제 링크 : https://github.com/seyoungcho2/Dagger2Example

@Component(modules = [PersonModule::class])
interface SchoolComponent{
fun injectStudent(student: Student)
fun injectTeacher(teacher: Teacher)
}
@Module
class PersonModule {
@Provides
@Named("Student")
fun providesStudentName() = "StudentA"
@Provides
@Named("Teacher")
fun providesTeacherName() = "TeacherB"
}
PersonModule에는 두개의 프로바이더가 있으며 각각은 @Named로 구분 된다.
class Student() {
@Inject
@Named("Student")
lateinit var name: String
}
class Teacher {
@Inject
@Named("Teacher")
lateinit var name: String
}
데이터를 담는 클래스인 Student와 Teacher은 각각 var name : String을 프로퍼티로 가지고 있으며 @Named로 어떤 프로바이더에 의해 주입받아야 하는지를 명시한다.
*RunExample.kt 파일
fun main(){
val personComponent : SchoolComponent = DaggerSchoolComponent.create()
val student = Student()
personComponent.injectStudent(student)
println(student.name) // StudentA
val teacher = Teacher()
personComponent.injectTeacher(teacher)
println(teacher.name) // TeacherB
}
자 이제 Student와 Teacher의 인스턴스를 만들고 주입을 시작한다. 그러면 각각 @Named에 의해 자신이 주입 받아야 하는 인스턴스를 주입 받게 된다.
따라서 name 프로퍼티의 출력값은 Student는 StudentA가 되고 Teacher은 TeacherB가 된다.
같은 타입의 Provider가 있을때 구분
앞서 Provider을 이용해 주입(Inject)가 되는 것을 보았다. 하지만, Provider만 사용하여 주입하는 것에는 문제점이 있다.
바로 Provider에서 제공(Provide)하는 인스턴스의 타입이 같을 때 어떤 인스턴스를 주입해야 하는지 모른다는 것이다.
예를 들어 아래와 같은 Module이 있다고 해보자.
@Module
class PersonModule {
@Provides
fun providesStudentName(): String = "StudentA"
@Provides
fun providesTeacherName(): String = "TeacherB"
}
이 모듈에서 제공하는 두가지 Provider의 반환 타입은 모두 String이다. 이 때 String 값을 아래 Student Class의 인스턴스에서 주입받고자 할 경우 어떤 Provider에서 주입 받아야 하는지 알 수 없다.
class Student() {
@Inject
lateinit var name: String
}
이를 그림으로 표현하면 다음과 같다.

Person Module 내에 같은 타입을 반환하는 Provider가 있어 주입 시 어떤 Provider을 주입시켜야 하는지 모르는 것이다.
@Named Annotation을 이용한 같은 타입 Provider 구분
이를 해결하기 위해서는 @Named Annotation을 활용한다. @Named Annotation은 같은 타입 클래스의 인스턴스를 제공하는 Provider가 두 개 이상 있을 때 그 둘을 구분해주는 역할을 한다.
제공하는 쪽(Provider)과 주입 당하는쪽(Inject) 모두에 @Named Annotation을 사용해야 구분이 되므로 둘 모두에다가 @Named Annotation을 붙여야 구분이 주입이 가능해진다.
위의 <그림1>을 <그림2>와 같이 바꾸면 Student에는 Student 이름의 주입이 가능해진다.

제공(Provider)하는 쪽의 fun과 주입받은 Student 에 모두 @Named 를 붙임으로써 Student가 어떤 Provider로부터 name 프로퍼티를 주입 받아야 하는지가 명확해졌다.
예제4에서 이에 대해 다루도록 한다. 먼저 예제4의 파일 구조는 다음과 같다.
예제 링크 : https://github.com/seyoungcho2/Dagger2Example

@Component(modules = [PersonModule::class])
interface SchoolComponent{
fun injectStudent(student: Student)
fun injectTeacher(teacher: Teacher)
}
@Module
class PersonModule {
@Provides
@Named("Student")
fun providesStudentName() = "StudentA"
@Provides
@Named("Teacher")
fun providesTeacherName() = "TeacherB"
}
PersonModule에는 두개의 프로바이더가 있으며 각각은 @Named로 구분 된다.
class Student() {
@Inject
@Named("Student")
lateinit var name: String
}
class Teacher {
@Inject
@Named("Teacher")
lateinit var name: String
}
데이터를 담는 클래스인 Student와 Teacher은 각각 var name : String을 프로퍼티로 가지고 있으며 @Named로 어떤 프로바이더에 의해 주입받아야 하는지를 명시한다.
*RunExample.kt 파일
fun main(){
val personComponent : SchoolComponent = DaggerSchoolComponent.create()
val student = Student()
personComponent.injectStudent(student)
println(student.name) // StudentA
val teacher = Teacher()
personComponent.injectTeacher(teacher)
println(teacher.name) // TeacherB
}
자 이제 Student와 Teacher의 인스턴스를 만들고 주입을 시작한다. 그러면 각각 @Named에 의해 자신이 주입 받아야 하는 인스턴스를 주입 받게 된다.
따라서 name 프로퍼티의 출력값은 Student는 StudentA가 되고 Teacher은 TeacherB가 된다.