Hi all. I'm new to DI in general, and I'm looking ...
# koin
s
Hi all. I'm new to DI in general, and I'm looking at the concepts now in the context of application plugins. In my Kotlin (desktop) application I'm currently using Java's good old
ServiceLoader
to discover plugins on the classpath. After reading through https://itnext.io/serviceloader-the-built-in-di-framework-youve-probably-never-heard-of-1fa68a911f9b it occurred to me that
ServiceLoader
can also be thought of a DI framework. So if
ServiceLoader
is a DI framework, I was asking myself if Koin could also be used as a plugin framework? Is there a way to discover (unknown) components that implement an interface on the classpath with Koin, and make them available to the application?
s
intriguing question, I am myself working on a plugin system but unaware of koin internals, would like to know this if it can be achieved...? Koin does work by declaring modules and if there are components on classpath which we want to inject, I guess we would need to have a manuall traverser to get components from the classpath of signatue which we want and then maybe koin can inject it. I think the above can be converted into a helper extension function,taking signature and mapper for creating an instance from classpath and load them all up into koin.
a
yes, you can request a collection of definitions of a given type. For example, getting all instances of type
Plugin
with
koin.getAll<Plugin>()
for example
s
Thanks. However, don't all components / component instances need to be known at compile time in order to add them to the
module
? That's not the case for plugins which could be provided by adding JARs to the classpath at runtime.
a
Koin is entire dynamic. You request the definition registry where it can be updated anytime. No need of compile time stuff here.
s
Right. But what I mean is: In order to know which classes (provided by plugins) to instantiate dynamically to add them to the
module
, I still need the `ServiceLoader`mechanism to discover those classes, right? I.e. there is no way to get rid of the
ServiceLoader
mechanism by using Koin alone, but I need to use both,
ServiceLoader
and Koin, correct?
a
Koin can already be used for plugin discovery, and inject them where you need
you can even ask Koin to create instances at start
s
Is there somewhere an example for the plugin-discovery use-case? If not, can we maybe get one? 🙂
So more concretely, if I have a bunch of exporter plugins and a module definition like
Copy code
module {
    singleOf(::CsvExporter) bind Exporter::class
    singleOf(::ExcelExporter) bind Exporter::class
}
how would I know what to use as a parameter for
singleOf()
if the class / constructor name is not known at compile time, as the JAR with the exporter might only be added at runtime?
a
the singleOf form allow to fill every parameter of your constructor with get()
if there is no special parameter to pass in, it should go straight forward
s
Hmm, I still feel like we're talking past each other. I'll try to phrase it differently: What Koin-code needs to go into the plugin, and what Koin-code needs to go into the application that dynamically discovers plugins at runtime?
a
Your plugins doesn’t need to extend or use Koin API
the main application entry need to request all plugins with
getAll()
functions
s
But if a plugin does not use the Koin API to register itself as a component, how would
getAll()
be able to discover it? I'm sorry, I really need a full example analog to the
ServiceLoader
- based changes in https://github.com/sschuberth/stan/commit/190542c1aa1683d6694d2348a5f0ad860013c83c
s
+1, confused as well.