InsertKoinIO / koin

Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
https://insert-koin.io
Apache License 2.0
8.77k stars 695 forks source link

[koin-android] broken shared view model factory when migrating from 3.5.0 -> 3.5.3 #1831

Closed wax911 closed 3 months ago

wax911 commented 3 months ago

Describe the bug I recently upgraded to koin-android:3.5.3 from koin-android:3.5.0 and upon initial investigation it was apparent that the sharedViewModel or activityViewModel returns different instance between the parent activity and the child fragment (AuthScreen -> AuthContent):

2024-03-26 10:44:13.670  8030-8030  [Koin]                  co.anitrend                          D  (+) index 'co.anitrend.auth.component.viewmodel.AuthViewModel::_root_' -> '[Factory:'co.anitrend.auth.component.viewmodel.AuthViewModel']'
2024-03-26 10:48:26.782  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' ...
2024-03-26 10:48:26.782  8030-8030  [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look in injected parameters
2024-03-26 10:48:26.783  8030-8030  [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look at scope source
2024-03-26 10:48:26.783  8030-8030  [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look in other scopes
2024-03-26 10:48:26.783  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' ...
2024-03-26 10:48:26.783  8030-8030  [Koin]                  co.anitrend                          D  | (+) '[Factory:'co.anitrend.auth.component.viewmodel.AuthViewModel']'
2024-03-26 10:48:26.803  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' in 20.083463 ms
2024-03-26 10:48:26.803  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' in 21.12692 ms
2024-03-26 10:48:26.804  8030-8030  AuthScreen              co.anitrend                          D  co.anitrend.auth.component.viewmodel.AuthViewModel@edf5102
2024-03-26 10:48:26.877  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' ...
2024-03-26 10:48:26.877  8030-8030  [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look in injected parameters
2024-03-26 10:48:26.877  8030-8030  [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look at scope source
2024-03-26 10:48:26.878  8030-8030  [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look in other scopes
2024-03-26 10:48:26.878  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' ...
2024-03-26 10:48:26.879  8030-8030  [Koin]                  co.anitrend                          D  | (+) '[Factory:'co.anitrend.auth.component.viewmodel.AuthViewModel']'
2024-03-26 10:48:26.900  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' in 21.447902 ms
2024-03-26 10:48:26.900  8030-8030  [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' in 22.943066 ms
2024-03-26 10:48:26.901  8030-8030  AuthContent             co.anitrend                          D  co.anitrend.auth.component.viewmodel.AuthViewModel@ed61a0c

Confirmed to be related to koin 3.5.3, upon downgrading I and retesting I've confirmed to have fixed the issue

2024-03-26 15:13:05.022 21511-21511 [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' ...
2024-03-26 15:13:05.023 21511-21511 [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look in injected parameters
2024-03-26 15:13:05.023 21511-21511 [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look at scope source
2024-03-26 15:13:05.023 21511-21511 [Koin]                  co.anitrend                          D  |- ? t:'co.anitrend.auth.component.viewmodel.AuthViewModel' - q:'null' look in other scopes
2024-03-26 15:13:05.024 21511-21511 [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' ...
2024-03-26 15:13:05.024 21511-21511 [Koin]                  co.anitrend                          D  | (+) '[Factory:'co.anitrend.auth.component.viewmodel.AuthViewModel']'
2024-03-26 15:13:05.047 21511-21511 [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' in 23.052371 ms
2024-03-26 15:13:05.047 21511-21511 [Koin]                  co.anitrend                          D  |- 'co.anitrend.auth.component.viewmodel.AuthViewModel' in 24.343733 ms
2024-03-26 15:13:05.047 21511-21511 AuthScreen              co.anitrend                          D  co.anitrend.auth.component.viewmodel.AuthViewModel@edf5102
2024-03-26 15:13:05.117 21511-21511 AuthContent             co.anitrend                          D  AuthContent -> co.anitrend.auth.component.viewmodel.AuthViewModel@edf5102
2024-03-26 15:13:29.414 21511-21511 LeakCanary              co.anitrend                          D  Watching instance of co.anitrend.auth.component.viewmodel.AuthViewModel (co.anitrend.auth.component.viewmodel.AuthViewModel received ViewModel#onCleared() callback) with key 019716d5-5abf-42e8-ab8f-c49a142aa863

To Reproduce Steps to reproduce the behavior:

  1. Create an activity and fragment with a view model
  2. Inject the view model in your activity as normal
  3. use sharedViewModel or activityViewModel in the child fragment
  4. Log the instance id of the view model in both activity and fragment
  5. Switch between versions 3.5.0 and 3.5.3

Expected behavior We should have some level of assurance that the VM factory from the parent FragmentActivity loads the correct viewmodel instance if it meant to be shared.

Koin module and version:

arnaudgiuliani commented 3 months ago

yes, duplicated. Fixed in 3.5.4. ViewModel key generation is the cause 👍