18 September 2023
getInjector().inject(this) all the time?Unfortunately, we do.* Lets take a look at the history of DI frameworks in Java to understand why.
Once upon a time, Dependency Injection frameworks like Guice(created by Bob Lee) used reflection to achieve their DI. At the time, these DI frameworks weren't built with mobile devices in mind, they were built for servers. Reflection has a runtime cost in performance, but it's an appropriate tradeoff for a server environment. When mobile devices came along, this was no longer the case and led to app slowdowns. We needed a DI framework that was blazing fast for mobile devices but used less or no reflection.
Dagger 1, originally created by Square(Block now), used a mixture of code generation and reflection to achieve DI. At compile-time, the injecting code was generated by using annotations (@Inject) in your own code that the Dagger compiler would look at and process. It worked, but the reflection that was hanging around left a desire for more. What if we could make a DI framework that completely ignored reflection and just used code generation at compile-time? This would also yield a major advantage for Dagger 2: failing early. When a dependency couldn't be satisfied(it wasn't on the DI frameworks graph), developers would find out at runtime what had happened instead of compile-time. Early failures lead to faster fixes.
Thus, Dagger 2 was born. Dagger 2 skipped reflection entirely. Instead of making your users pay a performance cost, our Gradle builds would eat the cost in build time and generate injecting code at compile time. It was now possible to use a Dependency Injection framework without reflection.
This made DI with the assistance of a framework blazing fast and appropriate for mobile. We could have clean code without having to call a ton of constructors ourselves. But we have to hook into that generated code somewhere.
So, yes, we do have to call getInjector().inject(this) because this is how we hook into Dagger's
generated code. I'm skipping a lot for the sake of brevity but this is generally how injecting Fragments and Activities
on Android goes. Since we can't have custom constructors for Fragments and Activities(unless you're using minSdk 28) either,
this means we have to use Members Injection(not preferred).
— Daniel Perez