Dependency injection on Android with dagger-android and Kotlin
albertgao.xyz
albertgao.xyz
Kapt does bump the clean build time to about 2min, incremental builds take between 10-60s - although actually launching the app on an emulator/device adds another 20s.
The cons of Dagger2 that I've experienced since it's launch are; The documentation and support is useless. You're on your own of you don't use a 3rd party sample project as a template. No one understands scopes and subscopes, subcomponents etc. The new Android dagger api is arcane and weird, no one wants to use it.
The Dagger2 team should (if they aren't already) create a Kotlin extension for it, I believe there are some syntactic optimizations to be offered.
https://google.github.io/dagger/semantics/
It's not intended as a tutorial, so perhaps it won't quite meet your needs, but if you're curious how all the pieces fit together, it may help.
I think there are two reasons for this. First, is how scopes interact with Android component lifecycles, which make everything harder (like RxJava, etc) since they are a complexity multiplier.
Second, there are seemingly bizarre design decisions. For example, if you use dependent components (aka component dependencies), the syntax is pretty straightforward:
@Component { }
interface AppComponent { X,Y,Z }
@Component { dependencies = AppComponent.class }
interface LoginComponent { }
So the natural order of things is, components use modules, and components can depend on other components. Pretty simple.Subcomponents turns this relatively simple schema around. The documentation for subcomponents say:
> "To add a subcomponent to a parent component, add the subcomponent class to the subcomponents attribute of a @Module that the parent component installs."
I find is truly strange, now we have modules depending on (sub)components which is the inverse relationship as above.
If you value your build times or your sanity in the slightest, I'd recommend either severely limiting use of Dagger, e.g. by only using it in certain, small Gradle modules, or using a different DI solution.
Since then we have introduced Kotlin and Dagger and we are super happy with it.
As with Dagger, the learning curve is pretty steep. Having it working with modules + activities + fragments + architecture components has been a real challenge but we love it.
For those who are struggling with Dagger: version 2.10 introduced major changes for Android, for good reasons, but it made much harder to use and understand. Many tutorials focus on Dagger < 2.10. You probably should ignore those.
And for those who are going crazy with compilation times, Jrebel for Android is a huge time saver. It has an incremental compiler which works with annotation processors. They will stop supporting it in one year, but even then I think it is worth using it. Who knows: if enough people buy licenses maybe they reconsider killing it.
* monstrously big constructors (for carrying transitive dependencies)
* lots of @VisibleForTesting code to handle manually injecting various dependencies only for the sake of testing (poor man's DI and generally bad practice)
* a lot of factories (service locator or poor man's DI, essentially)
* code that's hard to unit test due to dependencies being hardcoded.
In other words, you'll either reinvent DI poorly, or give up on testability.
Then you have a mess without DI.