Whats the best way to pass an injected instance of...
# koin
m
Whats the best way to pass an injected instance of a class needed for a koin submodule? I have one module for an api that wants to take an `AuthProvider`implementation and use it in one of the bean definitions. In my app module im including
apiModule
and trying to inject an instance of
AuthProvider
in but i get a
NoDefinitionFoundException
on startup because its trying to get an instance of
AuthProvider
while build the dependency tree rather than lazily when an instance of
MyApi
is requested. I know i can move the
get()
call down into
apiModule
and have it just assume any callers will provide that in their own koin definitions, but id rather that dependency be more explicit
Copy code
// An api module that can expects an AuthProvider to handle requests  
val apiModule(authProvider: AuthProvider) = module { single { MyApi(authProvider) } 

// In my apps start up 
startKoin {
    modules(appModule(), apiModule(get())) // Cant get the instance from Koin here since it evaluates it eagerly before appmodule is setup 
}

fun appModule() = module {
    single<AuthProvider> { AppAuthProvider() }
}
I know this should work but then callers dont know from the function def of apiModule they need to include a component for Koin
Copy code
fun appModule() = module {
    single { MyApi(authProvider = get()) } 
}

// In my apps start up 
startKoin {
    modules(appModule(), apiModule()) // Auth provider is provided implicitly 
}

fun appModule() = module {
    single<AuthProvider> { AppAuthProvider() }
}
w
I built a pattern around this I call “QualifiedDependency” and “QualifiedConfiguration”. The idea is that qualified configuration tells consumers what you expect to have configured from outside your module and qualified dependency tells consumers about what you provide. You then use these types as qualifiers to flesh out your graph.
Copy code
sealed class ApiModuleQualifiedConfiguration {
    object AuthProvider : ApiQualifiedConfiguration()
}

sealed class ApiModuleQualifiedDependency {
    object ApiService : ApiModuleQualifiedDependency()
}
It helps a lot with discoverability as well as avoiding type collisions (we currently have 35+ gradle artifacts exposing koin modules)