Sign in Go Pro

Dependency Injection with Dagger 2

Matching Dagger Component Scopes with ViewModel Scopes

This lesson is for PRO members.

Upgrade today to get access to all the PRO lessons.

Unlock this lesson
Autoplay

Up next

Previous

About

In this lesson we learn how to make your Fragment’s component lifecycle match the Jetpack ViewModel lifecycle. This opens up possibilities (including not needing to rely on using ViewModel directly) for retaining state during your Fragment’s “user perceived” lifecycle.

I say “user perceived” because, your user doesn’t care that your Fragment was torn down due to a configuration change. As far as they’re concerned, they are looking at the same screen. I’ve found that the dependencies needed for each screen generally mirror that lifecycle as well.

This strategy is completely optional—use what works best for your use case—however I encourage it if you’re using injected ViewModels. If your dependencies are recreated on config change because you create a new Component, but you’ve already created the ViewModel for that screen, you may end up with mis-matched shared dependencies in injected components outside of your ViewModel.

Comments

Thanks for the awesome course,
I have couple of questions which I hope I can get a detailed answer from you:
1- as far as I understand, this approach is suitable for dynamic features, because of the appdeps module, am I right ?

2- What's the difference between ScreenScope and the ActivityScope, I can see that ScreenScope is tied to a viewmodel lifecycle, but can't get the difference between both when used in the flow you mentioned about credit card adding.

3- what if I have a dependency that I want it to be shared between details and home feature, and I don't want to put it in app level, I feel that creating a module like appDeps just for this is a bit overkill, couldn't figure out another way.

4- How to handle the lifecycle of a scope created to live in 2 features? like in question 3. I know we can go singleton or activity level, but can we go a little deeper like managing the scope lifecycle ourselves ?

5- the viewmodel lifecycle is managed by jetpack, if we need to share a viewmodel across fragments, how do we use activityViewModels instead of the viewmodel type?

6- Sorry for the wall of text, and thanks for the great content again.

  1. For the most part, yeah. Later in the course we depend directly on "feature" modules in the app module for determining which Fragment to show, so that would need a slight abstraction, but otherwise these modules are completely independent.

  2. ScreenScope will have scopes that mirror a Fragment's lifecycle, whereas ActivityScope mirrors the Activity lifecycle.
    For the banking example, you could have many screens used to complete a transaction, and those could share state in the ActivityScope (data about the transaction you're "building"), but have their own state in the ScreenScope.

  3. That's definitely not overkill! If multiple modules need to depend on something else, it should be its own module.

  4. You can create your own scope. Managing it would be up to you and require manual management since it would be independent of framework object lifecycles. This is a bonus to using Dagger 2 directly, instead of something like Hilt, for example. Complete control to put different scopes between others. Or you could have it completely separate and not, for instance, between the Activity and Screen scopes.

  5. You can get a view model like you would have otherwise. Just use the activity reference available in the Fragment to get a reference to it. The factory should work just fine for Activity scoped view models. Or, don't use ViewModel at all and just create an @ActivityScope injectable object.

  6. You're welcome, and no apologies needed!

Thanks alot for your answer, all clear now!
Have a great weekend.

>

Lessons in Dependency Injection with Dagger 2

1. Intro to Dependency Injection - Simple example with no DI
01:47
Brandon Gogetap
2. Intro to Dependency Injection - Dependency Injection in Practice
00:35
Brandon Gogetap
3. Why we use Dependency Injection
01:59
Brandon Gogetap
4. How Dependency Injection frameworks help
00:37
Brandon Gogetap
5. What we're building - Final Product
01:04
Brandon Gogetap
6. Creating the GitHub Browser Project
01:45
Brandon Gogetap
7. Creating the Application Component Interface
01:10
Brandon Gogetap
8. Building the Application Component
01:02
Brandon Gogetap
9. Dagger codegen: Inspecting the generated Application Component
00:47
Brandon Gogetap
10. Adding the GitHubApi Module
02:01
Brandon Gogetap
11. Creating a Dagger 2 Module
02:36
Brandon Gogetap
12. Creating the AppRepository - The single source of data for the UI
Pro
02:47
Brandon Gogetap
13. Dagger codegen: Checking in on the generated Application Component
Pro
02:41
Brandon Gogetap
14. Unit Testing the AppRepository
Pro
03:07
Brandon Gogetap
15. Feature: Home Screen
Pro
01:55
Brandon Gogetap
16. Home Screen Repository List Setup
Pro
04:40
Brandon Gogetap
17. Home Screen ViewModel
Pro
04:34
Brandon Gogetap
18. Injecting a Jetpack ViewModel
Pro
03:14
Brandon Gogetap
19. Exposing Singleton Dependencies in a Modular Way
Pro
02:34
Brandon Gogetap
20. Home Screen Component
Pro
04:01
Brandon Gogetap
21. Dagger codegen: Component Dependencies
Pro
03:16
Brandon Gogetap
22. Dagger codegen: Multibindings
Pro
02:31
Brandon Gogetap
23. Dagger codegen: @Binds, @Provides, and Modules
Pro
03:03
Brandon Gogetap
24. Matching Dagger Component Scopes with ViewModel Scopes
Pro
04:07
Brandon Gogetap
25. Unit Testing HomeViewModel
Pro
04:14
Brandon Gogetap
26. Displaying fake data in the Home Fragment
Pro
03:39
Brandon Gogetap
27. Espresso tests and Dagger: Modularizing ApplicationComponent
Pro
02:39
Brandon Gogetap
28. Espresso tests and Dagger: Adding the TestApplicationComponent
Pro
04:42
Brandon Gogetap
29. Espresso tests and Dagger: Adding the Test Application and Runner
Pro
01:49
Brandon Gogetap
30. HomeFragment Espresso Test
Pro
03:56
Brandon Gogetap
31. Retrofit integration: Suspend Functions
Pro
03:49
Brandon Gogetap
32. Retrofit integration: Preparing for the real GitHub API
Pro
04:00
Brandon Gogetap
33. Retrofit integration: Swapping mock GitHubApi with implementation created by Retrofit
Pro
04:11
Brandon Gogetap
34. Dagger Modules: Build variants/flavors
Pro
01:46
Brandon Gogetap
35. Dagger codgen: Effects of Module changes
Pro
02:19
Brandon Gogetap
36. Feature: Repo Details Screen
Pro
01:20
Brandon Gogetap
37. Repo Details Component
Pro
01:55
Brandon Gogetap
38. RepoDetails ViewModel Part 1
Pro
01:40
Brandon Gogetap
39. Dagger codegen: Qualifier Annotations
Pro
01:30
Brandon Gogetap
40. Extending GitHub API: Single repository fetch
Pro
01:31
Brandon Gogetap
41. AppRepository updates: Caching and new request
Pro
01:19
Brandon Gogetap
42. AppRepository Unit Test Updates
Pro
02:05
Brandon Gogetap
43. Repo Details Contributors List Setup
Pro
01:29
Brandon Gogetap
44. Repo Details View States
Pro
02:12
Brandon Gogetap
45. Repo Details ViewModel Test
Pro
01:35
Brandon Gogetap
46. Hooking up RepoDetailsFragment with View States
Pro
01:43
Brandon Gogetap
47. RepoDetailsFragment Espresso Test
Pro
02:34
Brandon Gogetap
48. Preparing for screen navigation
Pro
04:08
Brandon Gogetap
49. Activity Scoped Component
Pro
01:43
Brandon Gogetap
50. Activity Screen Navigator
Pro
02:04
Brandon Gogetap
51. Fake ScreenNavigator: A fake navigator for tests
Pro
01:12
Brandon Gogetap
52. Navigating from the Home screen to the Details screen
Pro
03:36
Brandon Gogetap
53. Dagger codegen: Walking through all the layers
Pro
06:03
Brandon Gogetap
54. PowerAdapter - A Dependency Injection driven RecyclerView Adapter
Pro
01:32
Brandon Gogetap
55. Using PowerAdapter for the Home screen
Pro
03:37
Brandon Gogetap