依賴注入是一種降低元件之間依賴的設計模式,將依賴轉移給依賴注入函式庫,不用關心物件實例誰產生或如何產生,也能避免實例層層傳遞的 anti-pattern。
層層傳遞實例的 anti-pattern
@Composable
fun A(vm: MyViewModel) {
// ...
B(vm)
}
@Composable
fun B(vm: MyViewModel) {
// ...
C(vm)
}
@Composable
fun C(vm: MyViewModel) {
// ...
vm.update()
}
使用依賴注入提供實例
@Composable
fun A() {
B()
// ...
}
@Composable
fun B() {
C()
// ...
}
@Composable
fun C() {
// 呼叫依賴注入函式取得實例
val vm: MyViewModel by inject()
vm.update()
}
Android 官方推薦使用 Hilt,我一開始也是使用 Hilt,不過後來比較喜歡 Koin 就換過去了。
Hilt 是簡化版的 Dagger,是 Annotation-based Java 依賴注入函式庫,優點是編譯時期注入,可以在編譯階段就發現錯誤,而且在編譯時就做完注入速度會相較快,對行動裝置來說更是重要,不過也是把雙面刃,代表在運行時發生錯誤會比較難追蹤。
Koin 是 Kotlin 依賴注入函式庫,優點是學習成本較低,而且針對 Kotlin 特化,運用 Kotlin inline function 等機制動態注入,不使用低效率的反射、程式碼生成,不過缺點就是運行時才能發現注入錯誤且速度較慢。