Android/Dependency Injection

[Koin] 3. named 메서드를 이용해 같은 Type 객체 구분하기

반응형

예제 링크 :  https://github.com/seyoungcho2/KoinExample

예제 브랜치명 : example/example2 *브랜치 필수 확인

 

seyoungcho2/KoinExample

Koin Usage Example. Contribute to seyoungcho2/KoinExample development by creating an account on GitHub.

github.com

 

같은 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") 중 어떤 객체를 주입 받아야 할지 모르게 된다.

 

그림1. 주입 객체 구분 오류 문제

 

때문에 런타임에 org.koin.core.error.DefinitionOverrideException 오류가 생기게 된다.

그림2. 객체 구분 못할 경우 오류 메세지

 

named 메서드를 이용한 같은 Type의 객체 구분

이를 해결하기 위해서 우리는 named라는 메서드를 이용한다. <그림3>와 같이 각 객체에 이름(name)이 붙어있다면 주입해야 하는 객체가 명확해질 것이다.

그림3. named 메서드를 이용한 주입 객체 구분

 

다음과 같이 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으로 주입해야 하는 객체를 명확히 구분이 가능해진다.

반응형
 

Kotlin 사용자 모임 오픈 카톡

오셔서 궁금한 점을 질문해보세요!

open.kakao.com

 

이 글의 저작권은 Kotlin World 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.