Scoped vs. unscoped Dagger dependencies

Eric N
1 min readMar 21, 2021

The code

1 activity app with 1 presenter. Full source code is here

MainActivityComponent

@Subcomponent(modules = [MainActivityComponent.MainActivityModule::class])
// @PerActivity
interface MainActivityComponent {
fun inject(mainActivity: MainActivity)

@Module
class MainActivityModule(private val mainActivity: MainActivity) {

@Provides
// @PerActivity
fun presenter(catRepository: CatRepository): MainPresenter {
return MainPresenter(catRepository, mainActivity)
}
}
}

PerActivity scope

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerActivity

Scoped dependencies

There’s a reference to the presenter in the generated code for the MainActivityComponent, allows Dagger to clear it automatically (when the activity is destroyed by the OS or by you)

As a result, the MainPresenter is only constructed once and reused by its clients afterwards.

Unscoped dependencies

In contrast to the scoped dependencies, there is no reference to the Presenter in the generated code for `MainActivityComponentImpl`!

Any time the presenter is requested, a new “loose” instance is created. There is no reusability in this case.

Conclusion

As many have said, scoping is expensive, so avoid it when you can. When you do use it however, it’s good to know the underlying so as to maximize its benefits and minimize its harm, besides of course, satisfying our curiosity :D

In my experience, reusability is often the double-edged sword in Java/ Kotlin and Object Oriented Programming in general. A lot of time it ended up being pre-mature optimization e.g. huge base classes. Dagger Scope or reusable dependency objects is just an example. It’s important to keep the balance and not get obsessed with reusability.

--

--