https://kotlinlang.org logo
Title
a

Antanas A.

04/26/2019, 11:55 AM
Hi, does any one knows a good dependency container to use in Kotlin for backend projects? Good means: work without any configuration and extra plumbing code in trivial cases. E.g. val di = Container.scanAllProject(); di.get(SomeService::class) would create and return a singleton of class "SomeService" with autowiring/resolving constructor injected dependencies automatically.
r

ribesg

04/26/2019, 11:59 AM
I use Koin everywhere I can use Koin (JVM & Android)
a

Antanas A.

04/26/2019, 12:05 PM
but for Koin there is a need to specify each class which will be created?
r

ribesg

04/26/2019, 12:07 PM
Of course, what else do you want to do?
s

streetsofboston

04/26/2019, 12:08 PM
Kodein is another DI framework. If I'm not mistaken, it supports multi-platform Kotlin
s

spand

04/26/2019, 12:08 PM
His question implies auto discovery
r

ribesg

04/26/2019, 12:09 PM
Does that exist?
c

Czar

04/26/2019, 12:09 PM
Spring, you still need annotations though. There is no magic 🙂
s

spand

04/26/2019, 12:13 PM
Well, you could use ie. https://github.com/classgraph/classgraph to find all subclasses of an interface and register them in your DI framework assuming it allows that on runtime.
t

tseisel

04/26/2019, 12:17 PM
Just noticed that Koin uses neither annotation processing nor reflection ... what does it use then ? DSL configuration at runtime ?
a

Antanas A.

04/26/2019, 12:21 PM
Yes, I'm thinking about using classgraph and then somehow call e.g. Koin or Kodein and register all found classes, but then It will need to register also all classes (dependencies) which appears on constructor
and on their constructors also
which seems is what I'm searching for, but using jitpack it not publishing any classes in .jar https://jitpack.io/#davidwhitney/kotlinject/52dbace6b7
s

spand

04/26/2019, 12:23 PM
Maybe you can use classgraph to find all classes which have a constructor with
@Inject
annotation (if that is what Koin etc. uses)
a

Antanas A.

04/26/2019, 12:25 PM
Koin seems is designed with reified inline functions in mind
so I don't know how to use their API in runtime
Looks like currently there is only spring container
t

tddmonkey

04/26/2019, 12:30 PM
Have you considered just not using a DI container?
a

Antanas A.

04/26/2019, 12:34 PM
yes, it's best approach and we're using just object with by lazy properties, but with a smaller project
t

tddmonkey

04/26/2019, 12:35 PM
It scales fine to larger projects too
a

Antanas A.

04/26/2019, 12:36 PM
in current project there is a need to have some type of "auto discover" of datasources commands mixins without explicit registration
s

Stephan Schroeder

04/26/2019, 1:42 PM
declaring dependencies in koin feels close to Spring's JavaConfig: val depModule = module(createOnStart = true) { single<CaseClient> { RESTCaseClient(get()) } single<TaskClient> { RESTTaskClient(get(), get()) } ... }
so not very much auto discovery going on here
s

sitepodmatt

04/26/2019, 1:45 PM
We use Koin on a server-side project but Im due to rip it out. Koin seems to be a good fit for Android where you dont have full control over how your app is insitated but outside of that it's horrid imo.
a

Antanas A.

04/26/2019, 1:59 PM
I'm currently testing Kotlinject and it seems best of all, it's port from .NET Ninject If someone also want to try it you can use jitpack: https://jitpack.io/#antanas-arvasevicius/Kotlinject/3e06747737 because original repository has only misconfigured maven and is not usable with jitpack.
c

Czar

04/26/2019, 2:08 PM
IFoo -> Foo naming convention
🤬
😂 1
a

Antanas A.

04/26/2019, 2:09 PM
yes.. see sharp 😃
managed to initialize magic container:
private val container = Container().apply {
    registrations.scan
        .fromClasspathWhere({ true }) {
            it.bindClassesAndInterfaces(
                condition = null,
                lifecycle = Lifecycle.Singleton
            )
        }
}
usage: val datasource = container.resolve(UserDataSource::class)
c

Czar

04/26/2019, 2:11 PM
tripple backticks for multi-line snippets
one
two
three
a

Antanas A.

04/26/2019, 2:11 PM
ty
👍 1
j

Joe

04/26/2019, 2:34 PM
fwiw, guice does this kind of 'just in time' binding by default if it can. recommend kotlin-guice for doing
injector.Instance<SomeService>()
instead of having to do a
::class.java
call.
a

Antanas A.

04/26/2019, 2:53 PM
how can I be forgotten about guice..
thanks @Joe I'll investigate if it fits our needs
I'd thought that guice always need to define everything explicit
I generally dislike annotation based configurations which guice suggests e.g.
@Inject @Named("SMSComms")
j

Joe

04/26/2019, 5:07 PM
yeah we mostly just
@Inject
primary constructors and use modules to specify anything more that needs it, with a few exceptions where we need
@Named
to qualify things