Easy Setup of Dagger2 and other Components in a Multi-module App using Clean Architecture
In my last article, I explained the migration of a single module to a multi-module using Clean Architecture and how it was structured.
In this part, I would like to share how I set up the codebase using Dagger2, Jetpack components (Navigation, Room), and Kotlin Coroutines in a simple process.
Scope
Like I mentioned previously, I will try as much as possible to avoid long read rather nosedive into the main business of the day—code setup.
Project Structure
Now that we have our modules structured as described in the last article alongside their respective contents, I will explain the code according to the modules and/or layers.
Setting up of Dagger2 in the core module:
@Compnent.Factory provides an easy way to provide application context into an object graph by annotating its parameter in a single method instead of individual methods (like that of @Component.Builder).
Since this is a multi-module, aside from the core component in the core
module, each feature module has its own component with the core component as a dependency. In the core module, there are just the CoreComponent
and CoreModule
as our dependency injection classes. Here we could provide the DatabaseModule
the application context. Also, in this module, I have the MainApplication
class.
Below are the snippets of the CoreComponent
, CoreModule
, and MainApplication
classes respectively.
The reason for initialising the repository class is that it is used across the feature modules, hence, it needs to publicly provided.
Here is how we create it in the application class:
From the above code gist, the two methods are created in order to inject DaggerComponent
in the Activity
and Fragment
classes of each module.
Check here to learn more about the @Component.Factory and other old ways of providing application context into an object graph.
Does this look easier? I guess, yes. So, let’s dive into creating the dagger component for each module. I will provide for a module.
For the competition
module, this is how the component looks like:
The ViewModel classes are provided in the usual way in the CompetitionsViewModelModule
class as seen below:
And this is how it’s injected in the fragment:
Setting up the Navigation Graphs in the navigation
module:
I mentioned in my last article that all the navigation classes are pulled together in a module to be accessed across all the modules.
Now, let’s see how the design looks like:
On the first page (i.e. the fixtures and competitions fragments), the graph has a separate layout (for competitions
module).
The second page (that contains the viewpager in the competitiondetails
module) has only the viewpager fragment class nav graph while the respective fragments in the viewpager are implemented in the usual way.
See the implementation below:
I know you’ve got some questions in mind like “since there are many feature modules, which one hosts the navigation graph”?
Well, the whole app uses a single activity pattern, so, the activity_main
hosts the navigation graph in the app
module. All settings relating to the navigation is done in the HomeActivity.kt
class as shown below:
What is contained in the data module
This module contains set up for room, coroutine dispatcher, repository implementation (which implements the repository interface defined in the domain
layer/module) and of course where all these are provided (for dagger usage) in the DataModule
and NetworkModule
classes.
I’m not able to include all the codes in this article but rest assured that you will find them here.
Conclusion
With the above steps, we have been able to set up some components (dagger2, navigation, etc.) with CA in a multi-module app.
And yes, you can check out an article I wrote about how I migrated this project to using hilt.
Thanks for reading through!
If you have any comment, kindly drop it in the comment section below and if you ❤️ this article, please feel free to 👏 and share.