3

I'm using Koin 3.2 which has the new module includes feature. In the official docs, when discussing module linking strategies, there is this paragraph:

An important detail to observe is that you can use includes to add internal and private modules too - that gives you flexibility over what to expose in a modularized project.

That is exactly what I need, but I can't find elsewhere in the docs how to set up a "private" module that only provides dependencies for the parent module, so that those child dependencies are not available for injection. E.g.:

class SomeNonInjectableClass
class SomeInjectableClass(private val sni : SomeNonInjectableClass)

val privateModule = module {
    singleOf(::SomeNonInjectableClass)
}

val publicModule = module {
    includes(privateModule)
    singleOf(::SomeInjectableClass)
}

In my main app I list the public module only, but automatically Koin provides all the included modules:

startKoin{
    androidLogger()
    androidContext(this@Main)
    modules(publicModule)
}

So now a developer can do this from any activity:

val foo : SomeInjectableClass by inject() //Ok
val bar : SomeNonInjectableClass by inject() //I don't want this

I want developers to not to be able to inject the non-injectable classes from the private module. Something like Dagger 2's @NonInjectable marker qualifiers.

Is this possible or should I resort to manually building my definitions using the classic DSL?

Mister Smith
  • 27,417
  • 21
  • 110
  • 193

2 Answers2

1

From what I've understood, this new includes feature simply makes possible to have the whole module definition private or internal, not allowing you to include them to modules outside this scope. I guess it has more to do with controlling the creation of Koin modules in large modularized projects than to be able to control what the developer can or cannot inject.

private val privateModule = module {
   singleOf(::SomeNonInjectableClass)
} 

I can understand how making this private to its scope can avoid some confusions when creating large compositions of koin modules across different kotlin modules (especially it there are a lot of definitions inside the private module) but at the same time I'm also frustrated that it seems it is not possible to achieve what you want to do.

cesonha
  • 334
  • 2
  • 9
1

To clarify: includes operator allow to load other modules with the given module.

If you want to avoid to share internal implementation, check your Gradle module exposure. For example, just share interfaces.

  • But I don't want to share anything. Eg.: Imagine a domain service module that imports a database module. I don't want anyone on the project to use the database module bypassing the domain service module. – Mister Smith Aug 23 '22 at 20:12
  • Injection visibility is linked to your compilation visibility. If you can't access the class, you won't be able to inject it. – Arnaud Giuliani Nov 07 '22 at 17:36