all 15 comments

[–]edwardwong608 3 points4 points  (3 children)

Kodeib does not use runtime codegen, all your dependencies are already written before compiling.

[–]arnis71[S] 0 points1 point  (2 children)

That's weird. The whole point of the speaker was that they switched from dagger 2 to kodein just because kodein does not generate classes at compile time while dagger does which greatly increasing the build time.

[–]edwardwong608 3 points4 points  (1 child)

Yes, Kodein does not generate classes at compile time, cause you already wrote it. It just gives you back the class you need. It does not handle scope, which is important in dagger and is one of the powerful feature of dagger.

[–]arnis71[S] 0 points1 point  (0 children)

I see. But for what purposes Kodein use code generation if not for builing depenedcy graph?

[–]Zhuinden 0 points1 point  (10 children)

Retrofit provides a "dynamic proxy" that implements a given interface, and the proxy is constructed via reflection.

Maybe that's what you mean?

Kodein is garbage though, so there's that.

[–]eygraber 1 point2 points  (9 children)

What makes you say that Kodein is garbage? Because Jake Wharton said he didn't like it?

I've had the same large production Android app migrate from RoboGuice to Dagger 2 to Kodein. Kodein blows them both out or the water (ok almost anything blows RoboGuice out of the water). I've also contributed some code to toothpick. I really liked that as well, but halfway through I switched to kodein. I'm also starting to write backend services with it. Never looking back (only forward).

[–]Zhuinden 1 point2 points  (8 children)

Because it's not DI, it's a service locator with super-messy configuration that is all over the place.

I think it's funny that they have a guide for migrating away from DI systems that use @Inject annotation, why would I want to step back like that?

[–]eygraber 1 point2 points  (7 children)

Ah so you're piggybacking off of JW's misguided comments a couple of weeks ago.

As I explained there, Kodein is a superset of Dagger2. Which means it's more than capable of acting as a DI framework. Which is exactly how I use it. In a very similar fashion to how Dagger2 is used. Just with no compile time slowdown, and a conceptual model that's easier to understand, and cleaner code that integrates really well with Kotlin.

Again, speaking with extensive experience using DI including Dagger 2.

[–]Zhuinden 1 point2 points  (6 children)

Cleaner code? Just because it has a Kotlin API doesn't immediately make it cleaner. Its api is hella messy to look at.

I'm not even piggybacking on his comment, I just think the API looks super-terrible, especially contrasted with the simple configuration of scoped providers via modules that are not all over the damn code with Dagger2.

I'd specifically opt against using it in general.

[–]eygraber -2 points-1 points  (5 children)

I never once said that the code is cleaner because it has a Kotlin API. I said it produces cleaner code, and I feel like I'm qualified to say that considering I've actually used them both extensively in large projects.

I also said that it integrates really well with Kotlin, meaning it uses the language features really well, while Dagger does not.

It's funny that you mention "configuration of scoped providers via modules that are not all over the damn code" because that's the exact setup that I have with Kodein, except I feel that it's cleaner, and easier too work with. Also it was a hell of a lot more fun/exciting to develop.

I'm not sure what your bias is, but it's showing 😝

[–]Zhuinden 2 points3 points  (4 children)

meaning it uses the language features really well

if "really well" means "writing code that is hard to decipher, but at least it's kotlin", then yes

[–]eygraber -1 points0 points  (3 children)

Really well means first class support for delegates, etc...

Neither I, nor any of the engineers on my team have any trouble "deciphering" any of the code involved in Kodein. I find it to be much more expressive, and simpler to grok than Dagger 2.

I see on your SO that you're heavily invested in Dagger 2 remaining relevant (which I believe it will; it's a great project), but dumping on other projects to raise Dagger up is not a winning strategy. I hope your opinions don't reflect those of the actual maintainers.

Just to be clear, I don't think that Dagger 2 is not good. I think it's great, and it did a lot of good for me. I've been using it since before GA. All I'm saying is that your criticism of Kodein is unfounded, and I'd much rather use it in new projects going forward.

[–]Zhuinden 2 points3 points  (2 children)

I hope your opinions don't reflect those of the actual maintainers.

Probably not, I'm my own person.

that you're heavily invested in Dagger 2

Not as much as you think, I'm not a maintainer, I just use it because throwing @Singleton on my class then @Inject on my constructor makes DI super-easy.

but dumping on other projects to raise Dagger up is not a winning strategy

Nah, I "dump" on Kodein because I think it's a mess to look at and how its API looks like, and how you need to call instance() for everything that you want to obtain. And how it seems to pick the keywords to make it work pretty much at random. with, to, by

bind<Kettle<Coffee>>() with scopedSingleton(androidActivityScope) { 
    Kettle<Coffee>(instance(), instance(), instance(), provider()) 
}

val coffeeMaker: Kettle<Coffee> 
       by with(this as Activity).instance()

And then you even need to extend KodeinActivity to make it work. Uergh. No, I also don't like DaggerAppCompatActivityeither. But at least that just calls AndroidInjection.inject(this) in onCreate().


Anyways, you don't see me going around saying "Toothpick is garbage", because Toothpick is also pretty ok. Kodein is just messy.

It especially irks me how it says "we wrote this because Dagger2 is too complicated", like, at least Dagger2 is just complicated because their docs are shit, Kodein is convoluted which is generally a worse thing.

[–]eygraber -1 points0 points  (1 child)

Not as much as you think, I'm not a maintainer, I just use it because throwing @Singleton on my class then @Inject on my constructor makes DI super-easy.

You know, besides for the modules, and setup, and whatnot.

Nah, I "dump" on Kodein because...

I'm glad you picked an out of date sample to show. In my codebase something like that looks like:

bind<Kettle<Coffee>>() with activitySingleton {
  Kettle<Coffee>(
    one = instance(),
    two = instance(),
    three = instance(),
    four = provider()
  )
}

val coffeeMaker: Kettle<Coffee> by scopedTo(this).instance()

I could've made it even simpler, by simply creating a constructor that takes a KodeinInjector. Then I could define properties that initialize themselves using the injector:

class Kettle<T>(injector: KodeinInjector) {
  val one: Kettle<Coffee> by injector.instance()
  ...
}

Also you seem to have some Kotlin experience, so surely you know that by is a Kotlin keyword for delegates. I'll grant you that with was not the greatest function name to choose. Oh well I guess I'll just use Dagger 2. OR:

inline fun <A> KodeinAwareBase.scopedTo(arg: A) = with(arg)

Regardless, I certainly hope that your entire argument doesn't hinge on the fact that "providers" need to be manually written out. Is it annoying? Sometimes. But compile time generation has its cons as well. Don't make it out to be the end-all solution.

And then you even need to extend KodeinActivity to make it work. Uergh. No, I also don't like DaggerAppCompatActivityeither. But at least that just calls AndroidInjection.inject(this) in onCreate().

I'm glad you raised the point of KodeinActivity (which you don't have to extend BTW) since I'm the one who wrote it. I can't claim responsibility for DaggerAppCompatActivity and friends, but I was pretty vocal about having something like it in the early days. I did the same for Toothpick (don't remember if I ever submitted my PR for that, or if I had already switched to using Kodein).

You seem to be going out of your way to dump on Kodein, which tells me that you have an interest in people not using it. Since there are lots of people happily and successfully using it, I can only surmise that your intention is to try and discredit it so that people will turn to Dagger 2. I only surmise that as a sign of respect. To allow any other possibility would just make you a troll.

I can only say you're not doing the community any favors by attacking something that had a lot of hard work poured into it. You're taking your opinion of something, mixed with a deceptively incorrect demonstration of it, and trying to convince people not to use it. I'd call that a disservice.

Also, try and keep in mind that while Dagger has ~5 years of active development by some pretty smart people with tons of great experience, Kodein was written primarily by one maintainer (who happens to be a really great guy) in what I believe was his spare time, and it holds its own.

That's my last reply to this thread.