Hi All, is the @Named annotation supposed to work ...
# koin
u
Hi All, is the @Named annotation supposed to work with Injecting a lazy dependency ? It seems I can not get it to work with koin 4.0.2 and koin-annotations 2.0.0-RC1. More in thread…
🚑 1
Here is what I have and it currently works.
Copy code
@Module
internal class ManagersModule {
    @Single
    fun provideOnAppUpdateListener(
        onAppUpdateListeners: List<OnAppUpdateListener>
    ) =  onAppUpdateListeners
}

@Single
internal class StartupManagerImpl(
    private val localSettingsRepository: LocalSettingsRepository,
    private val preferencesMigrationManager: PreferencesMigrationManager,
    private val onAppUpdateListeners: Lazy<List<OnAppUpdateListener>>,
) : StartupManager {
If I understand correctly, it will stop working though, as soon as I have another dependency of type
List
due to generics erasure and I need to put
@Named
annotations on
provideOnAppUpdateListener
as well as on the parameter
private val onAppUpdateListeners
. And that is where it stops working:
Copy code
@Module
internal class ManagersModule {
    @Single
    @Named("List<OnAppUpdateListener>")
    fun provideOnAppUpdateListener(
        onAppUpdateListeners: List<OnAppUpdateListener>
    ) =  onAppUpdateListeners
}

@Single
internal class StartupManagerImpl(
    private val localSettingsRepository: LocalSettingsRepository,
    private val preferencesMigrationManager: PreferencesMigrationManager,
    @Named("List<OnAppUpdateListener>")
    private val onAppUpdateListeners: Lazy<List<OnAppUpdateListener>>,
) : StartupManager {
This gives
Caused by: org.koin.core.error.NoDefinitionFoundException: No definition found for type 'kotlin.Lazy' and qualifier 'List<OnAppUpdateListener>'.
Btw, both versions, with and without
@Named
annotation pass module verification tests and the latter one only crashes at runtime.
And another “btw.” The whole setup would be obsolete if we had support for injecting lazies of list dependencies: https://github.com/InsertKoinIO/koin/issues/2126
a
yeah, lazy modules is not yet ready. Next release
seems that you cumulate Lazy & List type 😅
Lazy<List<OnAppUpdateListener>>
yeah, a corner case to fix 👍
u
Hi @arnaud.giuliani, thanks for your response. What do you plan for next release? • Fixing @Named annotations to work for Lazy? • Implementing Lazy and List to work together, out of the box?
a
• Fixing @Named annotations to work for Lazy?
yeah, will see if I can take it in 2.0 else next one
and yeah 2.1 to open soon for beta track and lazy modules
u
seems that you cumulate Lazy & List type 😅
Lazy<List<OnAppUpdateListener>>
Yes, there is a strong use case here, as getAll will potentially instantiate many instances. Our current use case is informing dependencies from our current Android application object about app updates. This happens (obviously) at app start and most the time the depndencies are not needed, as the app most the time has not been updated.
Things got worse with 2.0.0. My solution after this discussion worked nicely with 2.0.0-RC1 but now fails the Koin Configuration Check on 2.0.0:
Copy code
@Single
@Named(type = AppUpdateListener::class)
fun provideLazyAppUpdateListeners(): Lazy<List<AppUpdateListener>> = lazy {
    getKoin().getAll<AppUpdateListener>()
}

@Single
class NotifyAppUpdateStartupWork(
    @Named(type = AppUpdateListener::class)
    private val appUpdateListeners: Lazy<List<AppUpdateListener>>,
)
Copy code
> Task :app:kspProdApiDebugKotlin
w: [ksp] Koin Configuration Check ...
e: [ksp] --> Missing Definition for property 'appUpdateListeners : kotlin.collections.List' in 'skeleton.model.managers.startup.work.NotifyAppUpdateStartupWork'. Fix your configuration: add definition annotation on the class.
e: Error occurred in KSP, check log for detail
I also tried just providing
List<AppUpdateListener>
instead of
Lazy<List<OnAppUpdateListener>>
with no success.
I added a @Provided annotation to shut up ksp Koin Configuration Check and found out the issue is real:
Copy code
Caused by: org.koin.core.error.NoDefinitionFoundException: No definition found for type 'java.util.List' and qualifier 'skeleton.model.listeners.AppUpdateListener'
It does work at runtime if I only provide a List and leave the ‘lazy’ packaging to Koin. KSP config check still fails without @Provides:
Copy code
@Single
    @Named(type = AppUpdateListener::class)
    fun provideAppUpdateListeners(): List<AppUpdateListener> = getKoin().getAll<AppUpdateListener>()
Copy code
@Single
class NotifyAppUpdateStartupWork(
    @Provided // ksp Koin Configuration Check (v2.0.0) can't find the declaration
    @Named(type = AppUpdateListener::class)
    private val onAppUpdateListeners: Lazy<List<AppUpdateListener>>,
)
a
ok 🤔 interesting