일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- 코루틴
- 안드로이드 리싸이클러뷰
- MVVM
- android memory leak
- 안드로이드 Mockito
- android clean architecture
- 리싸이클러뷰 최적화
- 안드로이드 mvvm
- Android App Architecture Guideline
- 안드로이드 Espresso
- 안드로이드 앱 아키텍처 가이드라인
- Hilt
- android DI
- 안드로이드 최적화
- sharedFlow
- RxJava
- Android MVVM
- 안드로이드 JUnit
- Koin
- 안드로이드 mvvm예제
- coroutine
- 안드로이드 아키텍처 컴포넌트
- 안드로이드 앱 아키텍처 가이드라인 예시
- 안드로이드 앱 아키텍처 가이드라인 사용법
- 안드로이드 클린 아키텍처
- 안드로이드 hilt
- 안드로이드 의존성주입
- 안드로이드 테스트코드
- 안드로이드 앱 아키텍처 가이드라인 설명
- 스타트업 코딩테스트
- Today
- Total
안드로이드 연구소
[여기가 DI 설명 제일 잘함] Koin vs Hilt 본문
지난 번 의존성 주입 첫번째 포스터에서 의존성 주입(DI)이 뭔지 알아보았고
의존성 주입 두번째 포스터에서 안드로이드 의존성 주입(DI)라이브러리 2가지 Dagger와 Hilt를 알아보았습니다.
그렇다면 오늘 마지막 의존성 주입(DI)라이브러리 코인에 대해서 알아보겠습니다.
Q1. Koin에 대해서 설명해줘.
Koin은 JetBrains에서 개발한 Kotlin용 경량 의존성 주입 프레임워크입니다.
안드로이드 앱 뿐만 아니라 Kotlin 애플리케이션의 의존성을 관리하는 간단하고 실용적인 방법을 제공합니다.
DI 구현하는 간단하고 실용적이며 낮은 러닝커브로 쉽게 사용할 수 있도록 하는 것을 목표로 합니다.
Koin의 특징으로는 아래와 같이 있습니다.
1. DSL 선언
Koin은 DSL(Domain-Specific Language)을 사용하여 종속성을 선언합니다.
이 DSL을 사용하면 종속성이 제공되고 해결되는 방법을 지정하는 모듈을 정의할 수 있습니다.
2. Scope 관리
Koin은 종속성 Scope 지정을 지원합니다. 모듈에 대해 서로 다른 Scope를 정의할 수 있습니다.
Scope를 사용하면 의존성의 수명 주기 및 공유를 제어할 수 있습니다.
3. ViewModel 지원
Koin은 Android의 ViewModel을 기본적으로 지원합니다.
by viewModel()를 사용하여 ViewModel에 종속성을 주입하는 편리한 방법을 제공합니다.
Koin은 DSL이라는 언어를 사용하여 의존성 주입을 핵심으로 사용하고 있는듯합니다.
그렇다면 DSL이 무엇인지 알아보아야겠네요.
Q2. DSL이란?
Koin은 DI모듈을 구성하고 정의하기 위해 특별히 설계된 DSL을 제공합니다.
이 DSL은 표현력 있고 간결한 구문을 제공하여 모듈 및 해당 의존성을 선언하는 프로세스를 단순화합니다.
DSL을 사용하면 아래의 해당 함수들을 정의할 수 있습니다.
1. module function: 모듈을 정의하는 데 사용됩니다.
2. single function: 싱글톤 의존성을 선언하는 데 사용됩니다.
3. factory function: 팩토리 함수와의 의존성을 선언하는 데 사용됩니다
4. viewModel function: Android ViewModel에 해당하는 종속성을 선언하는 데 사용됩니다.(Koin에서 제공하는 편의 기능)
5. get() function: get() 함수는 모듈에서 종속성을 검색하는 데 사용됩니다.
5가지 함수를 사용한 예시입니다.
val myModule = module { single<MyDependency> { MyDependencyImpl() } factory { OtherDependency(get()) } viewModel { MyViewModel(get()) } }
으흠 그냥 이해하기는 많이 힘드네요.
그냥 저렇게 5가지 함수가 있구나 정도로만 생각하고 다음 진행해보겠습니다.
지난번 Dagger와 hilt와 똑같이 아래 viewModel예제에서
Koin을 사용한다면 어떻게 바꿀 수 있는지 확인해보겠습니다.
class UserViewModel : ViewModel() {
private val userRepository = UserRepository()
// using userReposiroty instance ...
}
Q3. 위 예제를 Koin을 사용한 예제를 보여줘
import org.koin.core.module.Module
import org.koin.dsl.module
import org.koin.core.context.startKoin
import androidx.lifecycle.ViewModel
import org.koin.core.context.GlobalContext
class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
init {
initializeKoin()
}
override fun onCleared() {
stopKoin()
super.onCleared()
}
// Function to retrieve an instance of UserViewModel
fun getUserViewModel(): UserViewModel {
return GlobalContext.get().koin.get()
}
// Other functions and logic in UserViewModel...
}
// Koin DSL 모듈 정의
val myModule: Module = module {
single<UserRepository>()
viewModel<UserViewModel>()
}
// Koin초기화 & module불러오기
fun initializeKoin() {
val koinApp = koinApplication {
logger(PrintLogger())
modules(myModule)
}
}
// UserViewModel의 인스턴스
fun getUserViewModel(): UserViewModel {
return koinApp.koin.get()
}
// Koin종료 & modules제거
fun stopKoin() {
koinApp.close()
}
;;; 이해는 가지만 세팅해주어야할게 생각보다 많아서 당황스럽다.
위에 얘기한 느낌으로는 Hilt보다도 코드가 간소화된 줄 알고 기대했었는데.
간단하게 정리한다면 Koin DSL로 모듈에
UserRepository와 UserViewModel 가장 해당되는 클래스의 함수를 세팅한다.
그리고 Koin을 초기화하고 module을 불러와서
파라미터로 불러온 userRepository인스턴스를 사용한다.
끝나면 Koin을 종료하고 불러온 module도 제거한다.
글로는 어떻게 보면 세팅하고 사용하고 종료하는 간단한 시스템인데
생각보다 기본적으로 세팅해줘야할 함수들이 많은 것 같다.
Q4. 엑티비티에서 Koin을 사용한 예제를 보여줘
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import org.koin.android.ext.android.inject
import org.koin.android.ext.android.startKoin
import org.koin.core.context.loadKoinModules
import org.koin.core.context.stopKoin
import org.koin.dsl.module
class MyActivity : AppCompatActivity() {
private val userRepository: UserRepository by inject()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Now you can use the userRepository instance in your Activity
}
override fun onDestroy() {
super.onDestroy()
stopKoin() // Koin 종료
}
}
// Define the Koin module
val myModule = module {
single<UserRepository>()
}
// Koin실행 & 모듈 불러오기
fun startKoinForActivity(activity: AppCompatActivity) {
startKoin {
androidContext(activity.applicationContext)
modules(myModule)
}
loadKoinModules(myModule)
}
엑티비티라고 크게 달라진 요소는 없었습니다.
private val userRepository: UserRepository에서 by inject()를 사용하는 점만 빼고요.
그렇다면 이렇게 세팅해줘야할 것도 많은 Koin을 Hilt대신 사용해야할 이유가 있을까요?
저는 한가지 Koin의 장점으로 본다면
DSL 모듈 세팅만 해주고 보일러 플레이트 코드인 Koin실행만 해주면 의존성 주입을 할 수 있다.
Hilt에서는 @Inject, @Module, @Component, @AndroidEntryPoint
위 어노테이션이 어떤 경우에 사용되는지에 대한 사전 지식이 있어야하지만
Koin은 Repository는 single, viewModel은 그냥viewModel DSL정도라고만 알고 세팅을 해두면
어떤 경우에서라도 의존성주입을 사용할 수 있기 때문에 러닝 커브가 낮은 것 같습니다.
그렇다면 새로운 DI라이브러리를 적용해야한다면
Koin과 Hilt중에 어떤 라이브러리를 사용하는것이 좋을까요?
Q5. Koin과 Hilt의 차이점에 대해서 말해줘
Koin은 어노테이션을 사용하지 않고 DSL언어를 사용하여 의존성 주입을 수행한다.
또 코틀린 프로젝트에 특화되있는 라이브러리이고 추후에 안드로이드용을 개발이 되었다.
Hilt는 Dagger의 기반으로 만들어져 어노테이션 위주로 의존성 주입을 수행한다.
이는 @Inject, @Module, @Component, @AndroidEntryPoint같은 어노테이션에 대한 이해가 필요합니다.
안드로이드에서만 사용되는 강력한 라이브리러이다.
이것도 역시 장단점이 분명히 보이는 것 같습니다.
Koin의 DSL언어는 Dagger나 Hilt의 어노테이션보다 러닝커브가 확실히 낮은 편인 것 같습니다.
하지만 Koin은 Hilt보다 안드로이드용 DI로써 최적화되어있지 않은 느낌을 주고 있네요.
아래 블로그에서 뱅크샐러드 기술 블로그에서 자신들이 기존에 사용하던 Koin을 사용하지 않고
Hilt를 사용하게된 이유에 대해서 설명을 해놓았습니다.
이유는 간단하게 안드로이드에서 확장성 있게 유연하게 사용하기가 힘들었기 때문으로 보입니다.
https://blog.banksalad.com/tech/migrate-from-koin-to-hilt/
뱅크샐러드 안드로이드 앱에서 Koin 걷어내고 Hilt로 마이그레이션하기 | 뱅크샐러드
…
blog.banksalad.com
그렇다면 저도 앞으로 DI를 배워야할 시점에서
Koin보다는 Hilt를 프로젝트에서 사용하는 것을 더 생각해보아야겠습니다.
하지만 항상 무엇인지 알아야지 판별할 수 있기 때문에 Koin에 대한 기초지식은 반드시 필요하다고 생각합니다.
또 시간이 지나면서 Koin이 어떻게 발전할지 시장에서 어떤 반응을 이어갈지 알 수 없기 때문에
Koin의 성장을 눈여겨 보도록 하겠습니다.
그럼 DI 의존성 주입에 대해서는 여기까지
'안드로이드 연구소 > 의존성주입' 카테고리의 다른 글
[Flow vs RxJava] RxJava(ReactiveX에 대하여) (0) | 2023.06.08 |
---|---|
[여기가 DI 설명 제일 잘함] Dagger1, Dagger2 그리고 Hilt (0) | 2023.05.17 |
[여기가 DI 설명 제일 잘함] 의존성 주입 하는 법 & DI 라이브러리들 (0) | 2023.05.16 |