On our latest article, what we did was creating a Dagger component about almost all of our features and provided a ViewModel(Factory) for every Fragment we had inside a module. As said, this is a little too much work for Dagger, the programmer and each feature. It's a total overkill of using Dagger actually, we could have stuck to a manual DI instead, but I required you to be patient.
Let me remind you of the current state of the app:
For simplicity I'm not saying in the picture that each component brings a ViewModel(Factory) to the component, please check the previous article if you are confused.
I am using a database only in 2 modules, :feature_2 and :feature_4. The rest of the app doesn't care about the database at all. Furthermore, :feature_2 has 0 relations to my :feature_4 entities, while this last one has 2 tables related to each other ( a one to many relationship). But this is not the problem yet. The problem is related to the database being exposed for all my modules. That's really unnecessary.
An optional solution:
We could create a :db_module and install it as a module inside the features that actually need it:
This solution would be great for modules whose entities have relations to each other. In my case it's too much. IMO, it's better to separate databases completely. I'll keep one database for my :feature_4 which has 2 related entities and another database for my :feature_2 which has only one entity. Plus, it requires less work in terms of time (even if we are creating 2 databases, isn't that cool😋 )
Completely separate databases:
In this way, the :feature_4 and :feature_2 not only are separated from all the other modules but they are also separated from each other.
We still have to do only dependency configuration only. This is good news:
This way I'm able to get the Application instance from my :core_module and provide it for my local database. And then I can do:
Now, the same rule should apply for the other module which needs the database configuration.
Can we do more?
Sure! The API calls are still centralized. What I mean is that methods of every API call are still exposed to all the modules. Furthermore, I am not using the same base URL. So I guess we should apply what we did to our Retrofit Interface too. Instead of having one interface with a lot of methods, we can have a lot of interfaces with the respective methods for the API call. I won't stop in the implementation for this case, but I guess the below image would give the message:
The same logic as the database configuration appeals to the retrofit modularization in code also:
There you go, now your modules are totally independent from each-other and our multi module app is 90% ready. The last part will be covering some short topics about my background-things (AlarmManager, WorkManager) and mostly resources, layouts and values.