Let’s play with different configurations and tests… in a multi-module app.
It has been 18 months since I published the first part of this post. That first part was about using dagger in different configurations and an easy playground app to play with:
- Dependent components.
- Subcomponents and builders
- Android injectors
Some months ago I added a new configuration with support for injection in a module, but with limited capabilities. Those configurations are implemented as different branches of the same repo in Github:
Since then, my team at Touch Surgery has been trying several ways of refactoring our dagger implementation in order to avoid the limitations of that system. Basically it meant creating different dagger graphs in each module and passing the dependencies from the main app module to the feature modules for those to include them in the module graph.
None of those solutions worked as we wanted. Recently we read this post from Marcos Holgado that seemed to be really close to what we were looking for. I won’t repeat here his explanation, so please use his post as a reference.
We implemented a custom version of Marco’s sample and it worked really well. So I have upgraded my Dagger playground repo with a new branch
Check the README file. There are several exercises for you to try. From investigating how app level or activity scoped singletons and multi-instance dependency are created to how to modify the injected dependencies during the Espresso testing.
The sample app is built with four modules:
- app: This is the application module. Contains the application class, the dagger graph root, and a sample activity that you can think on as one that is difficult to extract to a feature module. There is a singleton dependency that will be accessible all across this module and we will change for a different implementation in Espresso test time.
- module_core: Here we put all the app wide dependencies, like API access, Database, etc. We could have several dependency modules like this. In this sample we have two collaborators, one singleton and one multi-instance.
- module_main: Feature module. This contains the main activity that has access to core dependencies and this module collaborators. In both cases we have singleton and multi-instance samples.
- module_detail: Simple feature module to demonstrate how to navigate from main and to app activities.
The exercises in the README along with the logs will help you understanding the behaviour of the different injections:
Take a look to the different build.gradle files and check how app knows about every other module. Feature module knows about core module and if necessary, about other feature modules. Launching an Activity in the app module from a feature module is easy, even when the feature module knows nothing about the app one: Check the navigation from DetailActivity to AppActivity.
With this playground it will be easy for your team to test a configuration that suits your app and helps you to move to multi-module: Add Feature modules for your features and dependency modules with collaborators that mimic your Retrofit or database classes. Recreate the navigation of your app using empty activities or add fragments as convenient.
The new branch is fully Kotlin an I have also modernised other aspects of the repo. Old branches are also updated but still Java.