In the name of God
Today I’m going to go through all aspects of how I decided to go with Dagger as my DI library.
Before we start, let’s see what is AIO? AIO is the new side-project that I have been working on for a while now. AIO allows me to practice coding, implement new ideas, play with new tools, and a lot more. In this series of blogs, I’m going to cover pretty much all of the challenges, gotchas, recently learned stuff, and almost anything interesting to me during the development of this project.
At the beginning of AIO, I searched a lot and practice with a lot of tools to see which one suits me the best and which one I like to work with as DI for the project. I have been using Dagger as a DI framework for quite a while now and it has never let me down on anything. One of the trending topics these days is Dependency Injection vs Service Locator. Since I read and heard new libs are more Kotlin-ish and easier to work with I tried and implemented two medium-sized projects with Koin and KodeIn. As far as I liked them I really did not feel the way I usually do with Dagger. To give you an Idea here is a list of things I did not like about these libs:
- Service Locator
- Runtime Resolution
- No compile-time safety
- Using reflection heavily
- Scalability and Maintainability
I’m going to cover these points very briefly so here it goes:
The fact that my dependencies are all in one bucket (let’s forget about scopes for now) and the library has to find them (using their names) is not something I would call Dependency Management!. I have been using Android Framework Context.getSystemService(ServiceName) for a long time, and really I can not stop the feeling of this method failing now or now! This is what a ServiceLocator looks like to me. You do not really know where do those objects come from? Or even if you could find them at all?!
To be honest I really like Hollywood law which says: “don’t call us we call you”. When I use Dagger it really feels like my dependencies have been given to me automatically instead of asking for them or just passing objects to constructors!
With the libraries used today for SL (Koin/Kodein) when we ask for an object, it has to figure out the path to create that object (using lot’s of lambdas) at runtime instead of gluing every part in code and just calling the methods to actually create an object (DI).
No compile-time safety:
Having Dagger resolving every dependency at compile time and checking for my mistakes (like an autocomplete) is the greatest thing. It fails your builds fast and keeps exceptions away from users. Having SL on the other hand and the nature of them it’s almost impossible to do this at compile time.
Using reflection heavily:
As far as I know, The libraries I have used for SL depend on reflection to find your classes and create objects, we all know that using reflection (especially widely and on MainThread) is not efficient on Android.
Scalability and Maintainability:
This one is more of anticipation than a precise measurement or experience. With the way SL libraries work, I don’t really think they can scale as good as Dagger can.
Dagger has been around for a while now, has been heavily tested and used by many small and large projects. Stability is the key when developing a large scale app. Kotlin SL libraries, on the other hand, emerged recently and still have a long way to go
Cons of Dagger:
As far as I can remember everyone has been complaining about long Dagger compile time, but I don’t really see that as an issue anymore. with the help of incremental builds and new Dagger-Reflect (details soon), we can eliminate compile time waiting almost completely! my current build times are less than 5 seconds! (I know the project is not that huge yet!)
some people might say testing with Dagger is not easy and takes a lot of time. I kind of disagree! if you setup your DI good you should not really have much of a problem (going in details in the next episodes).
So with these points in mind and the many others, I think it’s clear which library I chose to go with on this project: Dagger.
So with having made this decision and putting away all the SL and DI headache, there is only one last thing to take care of before we actually going deep into implementation we need to make sure which version of Dagger are we going to use
Dagger2 or Dagger-Android.
I have been using Dagger-Android for a year now and I can confidently say that it’s a quicker and cleaner way of Dagger setup for Android projects. The caveats for me was that I could not use the entire Dagger features (ie: @BindsInstances, Scoping and …) easily or in some cases at all! Plus I’m not going to use Fragments at all (hopefully) and it’s going to be a single-activity with multi-views arch. Last but not least AFAIK Dagger-Android does not work with dynamic features. So Dagger-Android is not really going to help me here. That leaves me with one and only one option: Dagger2.
I can explain how I really setup DI using Dagger2 on AIO in the next post.
interested in AIO? make sure to have a look and even contribute on Github:
AIO on Github