Setting Up Android Modules With Dagger 2

Modular development is the way forward

Elye
Elye
Sep 15 · 5 min read
Photo by Clem Onojeghuo in Unsplash

In professional app development, the days when all Android code lives in a single gigantic app module will soon be over. Modular development is the way forward. Modularity promotes proper architecture set-up consideration and scalable development.

If we start a project with modularization in mind, we can set up the dependencies injection using Dagger 2. This piece will show you how, with a simple project illustration.


Project Assumptions

Here’s how we’ll set up our simple project:

  • There are three activities, where MainActivity could launch FeatureOneActivity or FeatureTwoActivity.
  • Each of the activities has its own dependency injected to it.
  • Each of the dependencies is injected with a singleton network and repository (i.e., the same copy is injected to all dependencies).

Project Modularization

For long-term scalability, assume we modularize based on activities. We could do it in other forms as well, this is just to simplify the illustration. We will have:

  • An app module containing the MainActivity
  • A feature one module that contains FeatureOneActivity
  • A feature two module that contains FeatureTwoActivity
  • And last but not least, the base module that stores all the common singleton class objects to be injected

Dagger 2 Set Up Challenge

To set up Dagger 2 conventionally, the simple links are:

Here we can see a challenge post for modular Android development. The circular dependencies are between the component and target objects, making it impossible for them to be in separate modules.

To be more specific, the target object usually also has a local dependency that needs to be injected through the local test-specific subcomponent.

In the above diagram, we can see that the same problem occurs: an indirect circular dependency between the target object, component, and target-specific subcomponent.

If we retain this linkage, we have no way to support Dagger 2 in different modules.


Dagger 2 for Modular Android

In order to solve the challenge above, we need to break away from using conventional single-graph Dagger 2, i.e.:

For modular Android, we’ll create multiple Dagger 2 graphs and connect them.

Base module

In the base module, we store all the dependencies needed by all the other modules. We create a single component named BaseComponent. We make it a singleton to ensure the same copy of all the dependencies is injected to anything that needs it.

The above code shows the BaseComponent. Note that we explicitly expose the baseNetwork and baseRepository so they can be accessed by the other Dagger 2 graph later.

This BaseComponent is generated at the BaseApplication for our app.

With this, we now have our dependencies module in place.

Feature modules

Each of the feature modules (including the app module) will have its own Dagger 2 graph generated. The graph generation is dependent on baseComponent.

There’s no circular linkage outside the module, hence baseComponent can easily be placed in another module.

In the above code, we see the linkage of FeatureComponent to BaseComponent. Note that we introduce ActivityScope, as we need a scoped component to be dependent on another scoped component (i.e. BaseComponent is singleton-scoped).

In FeatureActivity, we will generate the graph by accessing BaseComponent and supplying it to its FeatureComponent.

The feature module itself now has its own generated graph and is flexible enough to perform any Dagger architecture within as it required, such as setting up the needed subcomponents.

Overall set up

If we connect all the modules as described above, it will look like the diagram below. Each module has its own Dagger 2 graph generator, and they are each dependent on the base module’s BaseComponent.

This setup promotes the flexibility of Dagger 2 architecture within the module. It’s also expandable to another form of module partition that differs from the above example.

If you’d like to see the example code, here it is:


Conclusion

The above is good for a newly-set-up project, as you can plan all your main dependencies and place them in the base class. However, if you already have a gigantic project where most (if not all) of the code is already in the app module, how can you work with it? Check out the below

Also, in case Dagger is too complicated for you to wrap your head around, and you like to explore simpler approach, Koin is the other option. Check out the below artile.

Better Programming

Advice for programmers.

Elye

Written by

Elye

Learning and Sharing Android and iOS Development

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade