Upgrade to Pro — share decks privately, control downloads, hide ads and more …

大規模AndroidアプリのDIをKoinからHiltへ移行するTIPS

akkiee76
February 19, 2023

 大規模AndroidアプリのDIをKoinからHiltへ移行するTIPS

「potatotips #81 iOS/Android開発Tips共有会」の登壇資料です。

https://potatotips.connpass.com/event/272353

akkiee76

February 19, 2023
Tweet

More Decks by akkiee76

Other Decks in Technology

Transcript

  1. potatotips #81 Akihiko Sato / 株式会社ラクス Lead Engineer / @akkiee76

    SaaS 開発 (Backend, Frontend) / Mobile 開発 (iOS, Android) 上流工程、コードレビュー、チームの課題改善など 読書 / コーヒー / HHKB / あんバターフランス 自己紹介
  2. potatotips #81 DI ライブラリの移行のモチベーション Koin AndrodX ViewModel は JCenter の廃止により

    3.0.x の開発で終了し、  1. Maven Repository で提供されている io.insert-koin へ移行する  2. Android 公式の Hilt に移行する のどちらかの選択を迫られる状況に。
  3. potatotips #81 Koin の特徴 DI が直感的に実装できるライブラリなので、 中小規模のAndroidアプリ開発では導入がしやすい点が特徴。 val appModule =

    module { // Interfaceを用いてDIする single<Repository> { RepositoryImpl() } // ViewModelにDIする viewModel { MainViewModel(get()) } } class MyApplication : Application() { override fun onCreate() { super.onCreate() setupKoin() } private fun setupKoin() { startKoin { androidContext(this@MyApplication) modules(appModule) } } }
  4. potatotips #81 Koin 実装の課題 アプリの規模が大きくなってくると、module が肥大化し、 可読性が低下してくる。 val appModule =

    module { viewModel { parameters -> DetailViewModel(id = parameters.get(), get(), get()) } viewModel { DetailViewModel(get(), get(), get()) } viewModel { HogeDetailViewModel(get(), get(), get(), get(), get(), get()) } viewModel { FugaDetailViewModel(get(), get(), get(), get(), get(), get(), get()) } // 以降続く・・・ }
  5. potatotips #81 Hilt 移行のメリット ・ Andriod 純正ライブラリなので今後もメンテされる (おそらく) ・ いつかは乗り換えることになる

    ・ Jetpack ライブラリとの親和性 ・ 乗り換えによるモチベーションアップ ・ 生産性の向上 (テストコード書きにくい課題の改善) etc
  6. potatotips #81 Hilt 移行にあたって考慮するべきこと 1. Koin と Hilt は共存できるか ・

    場合によっては1バージョンで乗り換えできないこともある 2. 既存機能のデグレ 3. Koin で実装されたテストコードをどうするか
  7. potatotips #81 2. 乗り換えの基本方針を決める 2.1 module 実装の方針 interface UserRepository {

    fun getUsers(): List<User> } class UserRepositoryImpl : UserRepository { override fun getUsers(): List<User> { } } @Module @InstallIn(SingletonComponent::class) abstract class RepositoryModule { @Binds @Singleton abstract fun bindUserRepository(impl: UserRepositoryImpl): UserRepository }
  8. potatotips #81 2. 乗り換えの基本方針を決める 2.2 Fragment, ViewModel 実装の方針 @AndroidEntryPoint class

    MainFragment : Fragment() { private val viewModel: MainViewModel by viewModels() } @HiltViewModel class MainViewModel @Inject constructor( savedStateHandle: SavedStateHandle private val userRepository: UserRepository ): ViewModel() { ... }
  9. potatotips #81 2. 乗り換えの基本方針を決める 2.3 完了の定義 1. ViewModel から KoinComponent

    の継承が削除されていること 2. ViewModel の DI が by viewModels() となっていること 3. module から対象のコードが削除されていること 4. CI が成功していること
  10. potatotips #81 まとめ 1. 乗り換えの既存機能に対する影響を調査 2. 実装方針を確立する 3. 横展開で修正する 4.

    依存関係を削除 5. デグレチェック このプロセスで効率的に乗り換え作業が進められます。