Chapters

Hide chapters

Dagger by Tutorials

First Edition · Android 11 · Kotlin 1.4 · AS 4.1

15. Dagger & Modularization
Written by Massimo Carli

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the previous chapters, you learned about multibinding with Sets and Maps to improve the architecture of the Information Plugin Framework. With that information, you can add new features to the Busso App in an easy, pluggable and declarative way.

You’ve vastly improved Busso’s architecture, but there’s still room to make it even better. For instance, all the code is currently in the main app module. It would be nice to split that code into different modules to reduce the building time of your app while increasing its reusability and extensibility. But how can you do that with Dagger? Is it even possible?

The answer, of course, is yes! In this chapter, you’ll refactor the Busso App by moving some of the code from the main app module to other modules and changing the Dagger configuration accordingly.

Note: In this chapter, you’ll read the name module many times, referring to either the Gradle Module or the Dagger Module. To make everything clear, this chapter will refer to Gradle Modules as modules and Dagger Modules as @Modules.

What is modularization?

Modularization is the process of splitting the code and resources of your app into separate, smaller modules — in this case, Gradle modules. You can think of a Gradle module as a way to encapsulate code and resources. This makes it simpler to create a single library that you either use locally or publish in a repository like Artifactory to share with other developers.

A module might depend on other modules that you declare in the dependencies block of its build.gradle.

Note: You’ll use Gradle modules in this chapter, but the same concepts are valid with other systems, like Apache Maven or Apache Ivy.

Whether there’s a big advantage to using different modules in your app depends on how big and complex that app is. In general, using different modules gives you the following benefits:

  • Better organization and encapsulation of the code.
  • Shorter building time.
  • The opportunity to create libraries that make the code more reusable.
  • Better ownership management.

This chapter will cover each point in more detail, giving you the chance to improve Busso along the way.

Start by opening the Busso App from the starter folder of the materials for this chapter in Android Studio.

You’ll get an initial source folder structure, as Figure 15.1 shows:

Figure 15.1 — Initial Busso App source folders structure
Figure 15.1 — Initial Busso App source folders structure

As you see, there are a few new modules, one of which is libs.di.scopes.

At the moment, the new modules are all empty. To make your job easier, they already contain the dependencies you’ll need for this chapter.

Figure 15.2 — The Scopes module source files
Figure 15.2 — The Scopes module source files

Speaking of reusability, this module already contains the definition of the different @Scopes you created in the previous chapters. As you see in Figure 15.2, you have:

  • ApplicationScope
  • ActivityScope
  • FragmentScope

This module is very simple. It only depends on the javax.inject library, as you see by opening its build.gradle:

plugins {
  id 'kotlin'
}
apply from: '../../../versions.gradle'

dependencies {
  api "javax.inject:javax.inject:$javax_annotation_version"
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

You’ll learn all about the other modules later.

Better organization and encapsulation of the code

As you know, encapsulation is one of the fundamental concepts in object-oriented programming, but it’s also a principle to use in higher-level contexts like a library or a full architecture.

Ruvuca 98.4 — Qji Hosilicuis nusaho noabyo rapeg
Voxeso 54.4 — Bne Wopisazuif tasela qiotji ceziz

Defining an external @Module

As you know, you use @Module to tell Dagger how to create the objects that are part of a dependency graph. In this case, you tell Dagger which object to create to implement the Navigator interface. You do this in ActivityModule.kt, which is in the main app.

Reducing build time

In large, professional apps, you usually have thousands of source and resource files. As you learned above, a Gradle module is basically a compilation unit. It’s what you need to compile so you can build the archive you include as a dependency in other modules and apps, or upload the code to a repository.

Creating libraries

Right now, the libs.ui.navigation module is in the same Busso project. However, you could also publish it to an external repository and just leave a dependency to it in the build.gradle of the main app. In that case, it would be like any other external library you use, including Retrofit or Dagger itself. Having all classes and resources in the same app module increases build times and makes code harder to manage.

Ownership management

Suppose you contribute to an app with many features, and each feature has a different team responsible for developing and maintaining its code. Then, imagine if all the code was in the main app module.

Busso App modularization

Now that you know the main reasons to modularize, and you’ve seen the example of the libs.ui.navigation module, it’s time to continue refactoring the Busso App.

The networking module

In the starter project, the network package in the app module contains all the code you need for Busso’s networking layer. Look at this code and you’ll see that some of the definitions are:

Defining the networking configuration abstraction

The components you want to put in the libs.networking module might need some configuration values. To understand how this works, create a new file, NetworkingConfiguration.kt in the libs.networking module and add the following code:

Creating the NetworkingModule

Now, you need to create a @Module to tell Dagger how to create the object you need to connect Busso to the server using the configuration data the main app module provides.

Adding the dependency to the networking module

This step is very simple. Open build.gradle for the main app module and apply the following changes:

Adding NetworkingConfiguration to the app

libs.networking accepts some configuration data that you need to provide at runtime from the main app. Open Configuration.kt in the conf package and change it like this:

Adding NetworkingConfiguration to @ApplicationComponent’s dependency graph

Now, you need to tell Dagger that you want to use BussoConfiguration as the NetworkingConfiguration implementation to add to the dependency graph for @ApplicationScope. This will also make it available to the definition in NetworkingModule.

Updating NetworkModule.kt

Open NetworkModule.kt in the network package of the app module and change it to this:

What you achieved

With the help of the UML diagram in Figure 15.4, you can not get an overview of what you’ve achieved so far.

Tafanu 14.9 — Npu cubpixpafk luwuru UQX kiibxih
Jupuce 75.0 — Jwa sovyaylaxw sonisi UBR yaodbef

Zuwuru 12.3 — Rawmuxuw nuqulhezhael
Jukudu 60.7 — Gizgisek jimukcemroej

The location module

To modularize the location module, you need to make a few changes similar to the ones you already made for the networking module. In this case, you need to:

Vekira 99.3 — Nto Dogakuam Wp Xazuru
Weluyu 80.6 — Gke Fogiqiex Mp Suvero

The plugins module

Refactoring the Information Plugin Framework is the most complex example of modularization in the Busso App.

Quxeqa 90.3 — Oznadbegioh Lpizep Nwayiqath dacodcebyiis
Verana 29.3 — Ebkoxtugiaq Mmopat Dnufuqunb piyexwuxpaoc

Ceveri 52.7 — Rpu Kimcu Uxd
Zetiba 52.1 — Tle Bohda Atr

Key points

  • Modularization is a fundamental step in the development process of a project.
  • Splitting your code into external modules can improve the build time of your app and make your code more reusable.
  • Using external modules helps you to encapsulate the implementation details of your classes, making them available through @Provides definitions in local @Modules.
  • You set a simple Kotlin interface as the dependency for a @Component and use it to pass information from the main app to a dependent module.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now