3 ms·
Context receivers are also being considered as a poor man's DI/insane man's DI, depending on how you see it. Probably both. After all, if you have a class that
by ohgodplsno 4y ago
Context receivers are also being considered as a poor man's DI/insane man's DI, depending on how you see it. Probably both. After all, if you have a class that requires A, B and C to do its work, marking it as needing those three in context make it super easy to just always have to provide them.
Unfortunately (fortunately? Because I know the evil, disgusting things I would do if it was easier), right now you have to nest with(x) or x.apply { } blocks to have everything in scope. A with(a, b, c) { } syntax would be very welcome, but I don't think functions of type (A, B, C).() -> Unit are going to exist any time soon.
- yen223 4y agoI'm keeping an eye out on Kotlin's context receiver change, as I would much prefer a way to tackle dependency injection without using annotations and definitely without using XML. DI frameworks are already the insane man's DI.
- ohgodplsno 4y agoHave you considered something like Dagger + Anvil (https://github.com/square/anvil https://github.com/square/anvil) ? It works well enough that it gets out of your way. Is it doing insane things in the background at compilation time ? Absolutely. But it's worth it. And to save time in debug, you can shim in dagger-reflect to avoid the cost of having to run annotation processors.
- brabel 4y agoI would say the state-of-the-art today is Micronaut's DI [1]. [1] https://docs.micronaut.io/1.0.0/guide/index.html#ioc https://docs.micronaut.io/1.0.0/guide/index.html#ioc
- ohgodplsno 4y agoUh, that's a service locator with an annotation processor to discover injectable targets. It's far from being state of the art. It's like Koin, except slightly less manual. A far cry from automatically discovered injection
- brabel 4y ago> A far cry from automatically discovered injection Ok, then what's the wonderful DI system that has that? Micronaut was created by ex-Spring developers who had experience with all the earlier DI systems, including Dagger, Guice, PicoContainer etc. I would love to learn what people have come up with that's even nicer to use!
- vips7L 4y agoIMO the state of the art is Weld. With CDI lite you now can have compile time DI instead of having it resolved at runtime. https://weld.cdi-spec.org/ https://weld.cdi-spec.org/
- brabel 4y agoMicronaut DI is compile-time for almost everything.
- coutego 4y ago+1 for "insane". I'm honestly baffled by all this context nonsense in Scala, React and now Kotlin. Twenty years ago, Spring (among others) showed us how to do proper wiring of separate elements in a clean way. Everything was simple and crystal clear (if a bit verbose). Programming became mostly additive (rather than multiplicative) in complexity and programs could easily be broken down to pieces easy to understand and implement. And now we are back pass parameters to functions off-band like in the times of VB6? Seriously!? Get off my lawn...
- ohgodplsno 4y agoOff-band is a bit of a misnomer. The cases where you end up with enough context to actually be able to call these functions are either "oh god what the fuck are you doing" or "you nested with/applys on purpose". It doesn't magically conjure parameters out of thin air. It's an extension of receiver functions, where, if before you had a function that took A, B and C as dependencies, the best you could write was A.doThing(b: B, c: C, paramIActuallyNeed: Int), or wrap everything in a class (which goes against what Kotlin is trying to do). In addition, there are some actual interesting things to do with it! It's ultimately syntax sugar to hide external dependencies. If tomorrow all your calls to Int.add(other) need to all be logged to database, I'd rather add context(DatabaseWriter) and have all the benefits of it (including compilation errors), rather than polluting my function signature. It's not like Context providers in React or in Compose, where you just call and assume it's in scope and it crashes at runtime if it's not: context providers will not let you compile unless it is certain they are in scope. Traditional dependency injection is still very much done and the standard in Kotlin, except without the pile of crap that is declaring beans in XML