Dagger :
순수 Java로 구현된 DI 라이브러리며 의존성 주입 관계를 annotation을 이용해 컴파일 과정에서 주입
Koin :
순수 Kotlin으로 구현된 DI 라이브러리며 런타임 과정에서 주입
값 | 의미 |
---|---|
applicationContext | Koin 모듈을 생성한 application |
module | Koin 모듈을 정의할때 사용 |
viewModel | viewModel을 생성 (생명주기를 AAC 의 viewModel 과 동일하게 사용) |
single | 단일 인스턴스 (Singleton 동작) |
factory | inject 요청 시 새로운 인스턴스 생성 (Java의 new 객체) |
bind | 생성할 객체를 다른 타입으로 바인딩하고 싶을때 사용 |
get | 매개변수나 객체에 맞는 의존성을 주입 |
dependencies {
def koin_version = '3.2.0'
implementation "io.insert-koin:koin-android:$koin_version"
implementation "io.insert-koin:koin-core:$koin_version"
testImplementation "io.insert-koin:koin-test:$koin_version"
}
startKoin
추가class SampleApplication : Application() {
@KoinExperimentalAPI
override fun onCreate() {
super.onCreate()
val appModule = listOf(apiModule, viewModelModule)
startKoin {
androidContext(this@SampleApplication)
fragmentFactory()
modules(appModule)
}
}
}
모듈을 생성할 때 get()으로 주입시킬 수 있다.
val apiModule = module {
single {
Retrofit.Builder().apply {
baseUrl("https://api...")
...
}.build().create(ApiService::class.java)
}
}
val viewModelModule = module {
viewModel { SampleViewModel(get())}
}
class SampleViewModel(private val apiService: ApiService) : ViewModel() {
fun getApi() {
apiService.getApi()
}
}
by inject()를 통해 앞서 싱글톤으로 생성한 ApiService 객체를 초기화 없이 사용할 수 있다.
class SampleActivity : AppCompatActivity() {
private val apiService: ApiService by inject()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
apiService.getApi()
}
}
ViewModel을 주입하고 싶을 때
val viewModel: SampleViewModel by viewModel()
by viewModel()을 통해 주입할 수 있다.
장점
(1) Dagger에 비해 상대적으로 학습이 쉬움
(2) 순수 Kotlin이며 annotation을 사용하지 않기 때문에 상대적으로 가벼움
(3) MVVM 패턴의 ViewModel 주입을 쉽게 적용
단점
(1) Dagger에 비해 런타임시 오버헤드가 있음
(2) 런타임과정에서 DI를 주입하다보니 런타임중 Error가 발생할 수 있음
※ 런타임 : App이 최초 실행될 때 (Application이 호출될 때)
※ 오버헤드 : 어떤 처리를 하기 위해 들어가는 간접적인 [시간 · 메모리] 등을 말함