
Scoping Dagger Components with ViewModels
Android has never been so pleasant to work with: Jetpack and Architecture Components improved our lives in so many ways introducing easy ways to deal with Lifecycle, state retention and so many other common tasks that are part of every day’s Android Developer work.
One of the most popular ones is ViewModel which is the main component of Google’s Guide to App Architecture for Android together with LiveData.

What is so good about ViewModels?
- Easy to retain state/instance
What is not so nice about ViewModels?
- Extremely poorly named
- Forced inheritance
onCleared
callback- Factory to use custom constructors
Wouldn’t it be nice if we could get the advantages without the not so nice features?
TL;DR: The code can be found in this GIST.
ViewModel is a Retained Instance
What if I tell you that ViewModel is just a "retained instance" and any class, independent of your architecture, could use a ViewModel to retain state? This is clearly stated on Activity 1.0.0 release notes:
It is strongly recommended to use ViewModels to store non-configuration state…
What if we ignore the name and reimagine ViewModels as a simple way of retaining any instance?
Dagger Components as a ViewModel — Arch Component
Before we start, let's add Android-KTX libraries and Dagger dependencies to build.gradle
:

To make it easier to work with, let’s define a better naming for our ViewModels and few small delegate functions that will be responsible for creating those components.

Then, it is time to define our Dagger Component and scope it per Activity:


Here we have some new concepts: Instead of using the normal approach and defining our Dagger Component as an Interface, we'll need to use an abstract class
and inherit from ScopedComponent : ViewModel
.
@Component: Annotates an interface or abstract class…
Now, to test our setup let's define a few classes: a Presenter
scoped per Activity
that has a reusable Repository
dependency and a single Int
field called counter
, that will be the state we will preserve on configuration changes.


Now it is time to glue everything together.

That’s it. If you run this code and rotate the screen of the device you will see that the counter state will be preserved.
Conclusion
With few lines of code we manage to preserve Dagger Components in Configuration Changes, allowing us to scope our components based on the Activity
lifecycle and getting the following advantages:
- Use whatever name you want
- No inheritance
- No factory
Happy coding! 😎