예제 링크 : https://github.com/seyoungcho2/KoinExample
예제 브랜치명 : example/example2 *브랜치 필수 확인
같은 Type의 객체 여러개 주입 시 문제점
같은 타입의 객체가 두개이 이상이면 어떤 객체를 주입해야 할지 구분하는데 문제가 생긴다.
예를 들어 아래와 같은 주입을 한다고 해보자
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startKoin {
androidContext(this@MainActivity)
modules(
module {
single { Student("student-cho") }
single { Student("student-kim") }
}
)
}
val studentCho : Student by inject()
val studentKim : Student by inject()
findViewById<TextView>(R.id.textViewTeacher).text = studentCho.name
findViewById<TextView>(R.id.textViewStudent).text = studentKim.name
}
}
위의 코드를 돌릴 경우 studentCho 변수와 studentKim 변수는 Student("student-cho")와 Student("student-kim") 중 어떤 객체를 주입 받아야 할지 모르게 된다.
때문에 런타임에 org.koin.core.error.DefinitionOverrideException 오류가 생기게 된다.
named 메서드를 이용한 같은 Type의 객체 구분
이를 해결하기 위해서 우리는 named라는 메서드를 이용한다. <그림3>와 같이 각 객체에 이름(name)이 붙어있다면 주입해야 하는 객체가 명확해질 것이다.
다음과 같이 single 블록의 인자로 named를 넘긴다.
single(named("cho")) { Student("student-cho") }
single(named("kim")) { Student("student-kim") }
이렇게 하면 각 객체는 Type + 이름으로 구성되어 구분이 가능해진다.
inject를 할 때도 같은 방식으로 이름을 넘겨주면 같은 Type의 객체를 Injection 시 어떤 객체를 주입해줘야 하는지 구분이 가능해진다.
val studentCho : Student by inject(named("cho"))
val studentKim : Student by inject(named("kim"))
전체 코드는 다음과 같다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startKoin {
androidContext(this@MainActivity)
modules(
module {
/* 하나만 생성되고 재활용되는 Singleton Object 만들기 */
single(named("cho")) { Student("student-cho") }
single(named("kim")) { Student("student-kim") }
}
)
}
val studentCho : Student by inject(named("cho"))
val studentKim : Student by inject(named("kim"))
findViewById<TextView>(R.id.textViewTeacher).text = studentCho.name
findViewById<TextView>(R.id.textViewStudent).text = studentKim.name
}
}
이러한 방식으로 koin으로 주입해야 하는 객체를 명확히 구분이 가능해진다.
반응형