멤버 인젝션(Member Injection) 메서드
앞서 다룬 프로비전(Provision) 메서드에서는 Provider에 의해 제공되는 인스턴스를 반환하였다. 그와 달리
Member Injection 메서드에서는 인스턴스를 만든다음 Provider에 의해 제공되는 인스턴스를 주입시킨다.
이는 다음 두가지 방식으로 주입이 가능하다. 바로 필드 주입 방식과 메서드 주입 방식이다. 예제3과 함께 두가지 방식을 설명한다.
예제3은 다음의 코드 구조를 가진다.
예제 링크 : https://github.com/seyoungcho2/Dagger2Example
@Component(modules = [PersonModule::class])
interface SchoolComponent{
fun injectStudent(student: Student)
fun injectTeacher(teacher: Teacher)
}
@Module
class PersonModule {
@Provides
fun providesString() = "Example3 Name"
}
나머지는 아래에서 진행하면서 설명한다.
필드 주입(Field Injection)
필드 주입 방식은 필드가 정의된 인스턴스를 만든 다음 필드 자체에 값을 주입하는 방식이다. 필드 자체에 값을 주입하기 위해서는 다음과 같이 클래스를 준비해야 한다. 코틀린은 나중에 초기화하는 값에 lateinit을 써주어야 하기 때문에 다음 코드와 같이 Student class를 만든다.
class Student() {
@Inject
lateinit var name: String
}
이러한 Student에 다음의 코드로 주입이 가능하다.
fun main(){
val personComponent : SchoolComponent = DaggerSchoolComponent.create()
val student = Student()
personComponent.injectStudent(student)
println(student.name) // Example3 name
}
먼저 Student의 인스턴스를 만든 다음 아직 initialize 되지 않은 필드(name)를 주입하는 방식이다. 여기서 주입되는 값은 Provider에 의해 제공되는 값만 가능하다.
이를 시각적으로 표현하면 다음과 같다.
메서드 주입(Method Injection)
메서드 주입 방식은 메서드에 파라미터 입력해야 하는 값에 Provider에서 제공하는 인스턴스를 주입하는 방식이다. 메서드의 파라미터를 주입하기 때문에 다음과 같이 Teacher class를 준비한다.
class Teacher {
lateinit var name: String
@Inject
fun setTeacherName(name : String){
this.name = name
}
}
fun setTeacherName에서 파라미터로 받는 name 파라미터에 Provider에 의해 제공된 "Example3 Name" 값이 주입된다.
따라서 아래의 코드를 실행하면 Example3 Name이 출력된다.
fun main(){
val personComponent : SchoolComponent = DaggerSchoolComponent.create()
val teacher = Teacher()
personComponent.injectTeacher(teacher)
println(teacher.name)// Example3 Name
}
정리
지금까지 Component에서 Injection 메서드를 사용하는 방법을 살펴보았다. 주로 이번 글의 필드 주입 방식과 이전 3번 글의 생성자 주입 방식이 많이 사용되므로 잘 익혀두도록 하자.
Dagger은 내부는 복잡하지만 지금까지 다룬 작동 원리만 안다면 어렵지 않게 사용할 수 있다.
다음 글에서는 같은 타입의 인스턴스를 제공(Provide)하는 Provider가 여러개 있을 때 원하는 Provider에 의해 주입 받기 위해서 어떻게 해야 하는지를 다룬다. @Named Annotation을 이용해 다룬다.