hey guys what kotlin DI librarty would you recomme...
# android
m
hey guys what kotlin DI librarty would you recommend: Koin wither Kodein ?
b
Dagger 2 🌝
2
👎 1
m
why no use of new lib from kotlin?
r
Dagger 2
a
I'd recommend Kodein
1
r
Dagger 2 because it produces errors at compile time … And has more support. Its almost a standard like Retrofit, if you ask me. The Kotlin Libs use Functions. so you can get errors at runtime. w
But if your just doing a small project,I guess koin because it clean
👏 1
m
I'm just reading longg... longgg arguments betwwen dagger and kodelin on reddit: hard to conclude sth... however https://www.reddit.com/r/androiddev/comments/7awvhp/moving_from_dagger_to_koin_simplify_your_android/
a
The biggest problem here is, that Jake's posts always gets upvoted and appears at the top, but he just spreads superficial knowledge about alternative "DI libraries"
r
lmfao sheeh, blame it on Jake lol. But lets be real here , Dagger 2 is recognized by Google, If you want to be on the safe side.And plus Dagger 2 is very clean to implement, so what problem is Kodein solving that dagger 2 isn’t?
Like we can make a case for Anko vs XML, because Anko is faster. At the end of the day you can create your own DI framework, but if your going to use a third party in production, why would you really choose Kodein over Dagger 2?
a
@rkeazor eh, dont get me wrong. I have nothing against dagger. The only thing that bugs me is, that Jake still calls Kodein a Service Injector
so people will just listen to him and won't even take Kodein/Koin into consideration
r
judging by the implementation, i can sorta see why its considered that. Perhaps it just depends how you look at it. Its still a cool project tho, just don’t know if it beats out the popular alternative when it comes to production
lol lets just ask him. @jw can you tell us how you really feel lol
😂 1
j
Kodein and Koin are not DI libraries, period. You can write manual DI with them, but they're not injectors unless you choose to use reflection. So you can either lose IoC and do service lookup or retain IoC and do manual DI. Both of those options will scale poorly.
m
So far for me, the only purpose of using DI for was to inject DB and REST. From the my perspective I'm want tools to work just right after step up. I'm single developer of android application, I don't maintain any large app, and I don't want to bother of DI, i dont have time for it, so i want to be easy
a
@jw I won't argue with you anymore. I already proved to you that Kodein can be used as a DI framework (even on your terms), but you are still calling it a "Service Locator". So you are deliberately spreading only half of the information
j
You've only proved that it can be used to do manual DI via service location. It's a glorified Map.
Unless you're referring to the reflective JSR330 frontend? I'll happily agree that's actual DI!
r
🍿
2
all this over DI, at this point you might as well just use the new keyword and call it a day lol
But I can see @jw point, unlike dagger and let say swing, there is no way to keep IoC without using reflection.. @Andreas Sinz if you were to remove the semantic sugars of kotlin and have it purely written in java would you still feel the same way?
a
@rkeazor can you give me an example where dagger keeps IoC and Kodein needs reflection?
With java 8 it would require alot more code to achieve the same thing, but yeah, I feel that its still DI, because DI is defined as
In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object.
r
Hehe just when i thought i could finish my popcorn lol. Granted i havent used Kodien, but judging from the documentation alone , it looks like it uses a container to pass dependencies around. But remember IoC princpal is that the class should never care how the dependencies come be. But each class will know about Kodein
Kodein is more like a cute dsl for passing dependencies around. The difference between this and dagger is that with Dagger 2 the classes have no idea how these objects are created at most all you will see is a @inject.
Not saying Kodein is bad, i think its a cool library. But to consider it a fully fledge dependency injection framework, perhaps its not there yet
☝️ 2
a
@rkeazor if you judge by the README, i'm with you. There really needs to be (only?) a DI example in there.
If you completly rely on constructor injection, the classes do not even have to be altered at all
☝️ 1
Copy code
interface Foo

class FooImpl: Foo

interface Bar

class BarImpl(val foo: Foo): Bar

fun main(args: Array<String>) {
    Kodein {
        bind<Foo>() with singleton { FooImpl() }
        bind<Bar>() with singleton { BarImpl(instance()) }
    }
}
and if you need setter-injection (e.g. in Android to inject dependencies in your Activity, you can do it with
KodeinInjected
Copy code
class MyActivity : Activity(), KodeinInjected {
    override val injector = KodeinInjector()

    val random: Random by instance()

    override fun onCreate(savedInstanceState: Bundle?) {
        inject(appKodein())
    }
}
r
Yea but there is no IoC
j
That's service location
You're pulling dependencies out of a service provider
Same for the manual dependency injection example above. The library isn't performing DI, you do it manually using it as a service locator to fulfill those dependencies.
a
@rkeazor why is there no IoC?
@jw yes, in my second example its not DI, but I'll happily trade
@Inject lateinit var random: Random
with
val random: Random by instance()
, because DI is meant to decouple the classes from their dependencies. In the end, you either need to import
KodeinInjected
(Kodein) or
AndroidInjector
(dagger) inside your Activity class, so thats not really decoupling.
1
ad first example: yes, you have to write the glue code yourself, but dagger those the same thing under the hood. Lets recap what the DI pattern is:
In software engineering, dependency injection is a technique whereby one object supplies the dependencies of another object.
And thats exactly what happens in my first example. The classes get their dependencies through the constructor without knowing where they came from.
Kodein has alot of code that you'd have to write yourself if you were using an ordinary Map 😉 but I'm still not convinced that a library MUST create the glue code/wire the classes together at runtime automatically in order to be called a "DI library"
d
@jw I used to love dagger 2 until it came to making Android unit tests... I find it hard to manage flavours just for making a testing config...
But maybe I'm missing how to do it easily - I'm talking about Android components that can't have their constructors injected...
j
Those things shouldn't really be unit tested since that's an integration point with the OS framework. For integration tests of Android components you can supply a TestApplication without a test-specific flavor though.
d
@jw How do you replace the
Application.graph.inject(this)
, with TestApp.graph calls in onCreate, with if (Build.debug) all over? I know that it shouldn't be tested in general, but in certain cases, I need to assure that things don't get broken...
j
You should never refer to the application class directly. Use AndroidInjection.inject(this)
d
@jw That's an
object AndroidInjection
with an if(Build.debug) to know whether to return test graph or real graph? Then it would need an in it fun to be called from the app for building the graph? Is that what you mean?
j
No. Dagger's Android module provides an abstraction on retrieving the injector from the application class allowing the direct dependency on the application class to be removed and swapped out in tests.
d
I guess that's something relatively new, I'll check that out, thanks!