Reading Time: 4 minutes

In the name of God

Hi everyone,

Today I’m going to go through all aspects of implementing a good Dependency Injection (DI from now on) using Dagger on the AIO project.

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.

 

First things first what do we need? What is our final vision of our DI setup?

I need a modularized, Dynamic Feature compatible, extendable and Scalable setup so at least in the long run I would not have any problem.

A normal DI setup with Dagger on Android is like you create an AppComponent and define every application-scoped object there and then for every Activity (from now on: screen) you create another Component depending on AppComponent. This way you can access all the objects defined in App scope in your feature component. Simple isn’t it?


 

But this is only applicable if all of our code is inside a single Gradle module (from now on: project). If we pull out every feature into its own project we no longer have access to AppComponent in App project. How do we address this issue?

How about pulling out AppComponent interface into our Core project? Since all of our projects depend on core we can easily access the interface and depend our feature Components on AppComponent. For the sake of better naming, I’m going to rename AppComponent to CoreComponent.


 

But there are still a few more things to cover here. If we create a CoreComponent whenever we need it in our feature components (line 38) we are not really using a proper DI graph and all of the objects in CoreComponent will be recreated which we probably don’t want to.

In order to fix this issue, we have to create a single CoreComponent and reference it everywhere.

We can pull out App class into the core project too but then our App project is not serving its real purpose. So how do we get around it?

How about creating an interface called CoreComponentProvider which has a single function that returns CoreComponent. And then We implement this interface in our App class. This way any Screen that wants to create a FeatureComponent can access CoreComponent using ApplicationContext and CoreComponentProvider Interface. Without actually knowing anything about real Application class implementation.


 

with the help of these extension functions we can get access to CoreComponent even easier:


 

here is how a feature can build its graph now:


 

With that out of the way, we can almost say we are done. Are we really?!

We still have one more thing to take care of.

Before we pull everything out into their specific projects we could easily create a single Repository Dagger Module and provide its dependencies there since it was in App Project everyone could easily access it using AppComponent. But now in order for us to do the same, we have to create a Domain/Repository project and make our core project depend on the Domain project.

This way fails the rule number one of the core project which is being independent of any other project.

How do we fix this now?

Let’s create another project called (for sake of simplicity) DaggerCore and put every CoreComponent related class into that. DaggerCore

Now we can depend on our daggercore project on Domain project and easily define our Domain-specific classes/logic in there. This way every feature can access Repositories and models through CoreComponent. Providing Repos in CoreComponent

At the same time, we get a pure and independent Core project.

Also if we decide to create a DynamicFeature project we can do so easily in the same way as our normal feature projects. the reason for that is because accessing CoreComponent is through ApplicationContext and we have at least a Context everywhere in Android!

With that said I can say we have a good setup (for now) which will take care of almost every use case that we have. I guess we should not worry about Dagger or better to say dependencies anymore and can focus on developing and exploring even more!

You can find every detail and the real implementation of this and other posts in AIO.

interested in AIO? make sure to have a look and even contribute on Github:
AIO on Github

It’s been a long post. Thank you for staying with me during this process. Hope it helps

Happy Coding