Using Dagger in Dynamic Feature Module

Using Dagger in Dynamic Feature Module

In this blog, we are going to learn how we can setup Dagger in our project having Dynamic Features Module.

As we have already understood that how we can setup dagger in our Android project which has multi-module architecture in our last blog.

To check out how we can use Dagger in Multi-Module Architecture, Click here .

We will be extending our project which we worked on in our last project.

But before that, we need to learn how to create and setup a dynamic-feature module. To learn about how to do it, click here.

First, let's get a brief,

What are Dynamic features modules?

It is like any other module in android but only to be separated from the module. It is shipped with app bundles and a user can download or delete the module based on its requirement.

So, now let's get started.

Step 01.

First I will create a dynamic-feature module in the project from,

File-> New -> New Module and select Dynamic Feature Module

and we will name it as featureThree .

Step 02.

Then we will add,

android {
    ....
    dynamicFeatures = [":featureThree"]
}

in the app's build.gradle file.

In featureThree's build.gradle we will add the dependency for the app, base, and dagger, like,

implementation project(':app')
implementation project(':base')
implementation "com.google.dagger:dagger:2.27"
kapt "com.google.dagger:dagger-compiler:2.27"

and to support kapt in featureThree will use the plugin,

apply plugin: 'kotlin-kapt'

The setup for dependency is completed.

Step 03.

Now we will create an activity called FeatureThreeActivity in the featureThree module.

Now, in the featureThree module, we will create di package and we will create 3 sub-packages of component , module , and scope .

In the component package, will we add FeatureThreeComponent and update the code like,

@FeatureThreeScope
@Component(
    dependencies = [BaseComponent::class],
    modules = [FeatureThreeModule::class]
)
interface FeatureThreeComponent {

    fun inject(activity: FeatureThreeActivity)

}

To check about base features like BaseComponent and BaseModule, click here.

Now, we will create FeatureThreeModule in the module package,

@Module
class FeatureThreeModule {
}

and finally, we will create scope.kt file in scopes package and update the code as,

@Scope
@Retention(AnnotationRetention.SOURCE)
annotation class FeatureThreeScope

Step 04.

Now, finally, we will update the FeatureThreeActivity's code to implement the FeatureThreeComponent like,

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_feature_three)

    DaggerFeatureThreeComponent
        .builder()
        .baseComponent(InjectUtils.provideBaseComponent(applicationContext))
        .build()
        .inject(this)

}

We are not creating a new instance of BaseComponent here, but rather passing it from the base module. To know more click here.

Step 05.

Now we will inject the DatabaseService and NetworkService in FeatureThreeActivity and update the activity's code like,

class FeatureThreeActivity : AppCompatActivity() {

    @Inject
    lateinit var databaseService: DatabaseService

    @Inject
    lateinit var networkService: NetworkService

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_feature_three)

        DaggerFeatureThreeComponent
            .builder()
            .baseComponent(InjectUtils.provideBaseComponent(applicationContext))
            .build()
            .inject(this)

        Log.d("DaggerSample_Feature3", databaseService.toString())
    }
}

We are done setting up the dagger for this module.

Now, we need to test if implementing dagger in dynamic-feature module was a success or not.

So, we will check that the injection of DatabaseService and NetworkService in MainActivity and FeatureThreeActivity is getting the same memory allocation.

We will check, with the Log statement which we have added in the activity files.

Now, We will update the code in onCreate() of MainActivity, to open the FeatureThreeActivity using,

val intent = Intent().setClassName(this, "com.mindorks.sample.feature.three.FeatureThreeActivity")
startActivity(intent)

Now, if we run the app, we get,

DaggerSample_Main: com.mindorks.dagger.multi.module.base.data.DatabaseService@63d3f1
DaggerSample_Feature3: com.mindorks.dagger.multi.module.base.data.DatabaseService@63d3f1

So, here you can see that we are getting the same memory allocation for database service across different modules.

So, this is how we can use the dagger in dynamic feature modules.

You can find the complete project here.

Happy learning.

Team MindOrks :)