Update Dagger post with comments from Arun

Signed-off-by: Harsh Shandilya <msfjarvis@gmail.com>
This commit is contained in:
Harsh Shandilya 2020-01-22 11:55:15 +05:30
parent 3d1ed1164a
commit 559d864097
1 changed files with 21 additions and 1 deletions

View File

@ -8,6 +8,8 @@ description = "Dagger is universally intimidating to beginners and I want to cha
devLink = "https://dev.to/msfjarvis/dagger-the-easy-way-part-1-3l7b"
+++
> Updated on 22 Jan 2020 with some additional comments from [@arunkumar_9t2](https://twitter.com/arunkumar_9t2). Look out for them as block quotes similar to this one.
This is not your average coding tutorial. I'm going to show you how to write actual Dagger code and skip all the scary and off-putting parts about the implementation details of the things we're using and how Dagger does everything under the hood. If you're interested in that, [poke me on Twitter](https://twitter.com/MSF_Jarvis) that you really, really wanna know the implementation details of this and I'll grumble and consider it.
With that out of the way, onwards to the actual content. We're going to be building a very simple app that does just one thing, show a Toast with some text depending on whether it was the first run or not. Nothing super fancy here, but with some overkill abstraction I'll hopefully be able to demonstrate a straightforward and understandable use of Dagger.
@ -26,6 +28,10 @@ A Component defines an interface that Dagger constructs to know the entry points
A Module is any logical unit that contributes to Dagger's object graph. In simpler terms, any `class` or `object` that has declarations which tell Dagger how to construct a particular dependency, is annotated with `@Module`.
> _Arun's notes_
>
> Modules should be mentioned first here, as they're the smallest units of a Dagger setup, and Components build upon them. An alternate definition for a module can also be this: if we draw a graph, methods in @Module classes become the nodes and @Component is the holder of those nodes.
## Getting Started
To get started, clone the repository which contains all the useless grunt work already done for you. Use `git clone https://github.com/msfjarvis/dagger-the-easy-way` if you're unfamiliar with branch selection during clone.
@ -55,6 +61,10 @@ object AppModule {
What we're doing here, is marking our `AppComponent` as a 'singleton', to indicate that it needs to only be constructed _once_ for the lifecycle of the application. We're also annotating it with `@Component` for obvious reasons, and adding our module to it to indicate that they're going together. This is empty right now but that's going to change soon.
> _Arun's notes_
>
> Annotating with @Singleton is only effective when configured properly. For this to be a singleton, you need to ensure you're creating this only once and that's your responsibility to fulfill. This is part of scoping and is a great topic to be covered in part 2.
If you check `MainActivity`, you'll notice that we're using [SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences.html). To demonstrate the use of Dagger, I'm going to replace that usage with one provided through Dagger. For that to happen though, Dagger needs to know how to create a `SharedPreferences`. Let's get that going!
```kotlin
@ -73,7 +83,13 @@ If you pay attention to the [commit](https://github.com/msfjarvis/dagger-the-eas
## Initializing our component
Now for Dagger to know when to create this graph, it needs to be able to know how to initialize the `Component` we wrote earlier. For this, we'll be adding a factory that constructs the `AppComponent`. Since we need a Context to be able to create `SharedPreferences`, we'll make our factory accept a context parameter. Here's how the finished `AppComponent` looks like with the factory method.
Now for Dagger to know when to create this graph, it needs to be able to know how to initialize the `Component` we wrote earlier. For this, we'll be adding a factory that constructs the `AppComponent`. Since we need a Context to be able to create `SharedPreferences`, we'll make our factory accept a context parameter.
> _Arun's notes_
>
> Worth nothing that the reason we create a factory method accepting Context instead of letting Dagger provide is because we don't have hold of Context during compile time. The instance is created by Android system and given to us which we then use Factory to give it to dagger.
Here's how the finished `AppComponent` looks like with the factory method.
```kotlin
@Singleton
@ -109,6 +125,10 @@ class ExampleApplication : Application() {
}
```
> _Arun's notes_
>
> Nit: I like to do something like [this](https://github.com/arunkumar9t2/scabbard/blob/004116cf6a548022982c7869d7758725c18991f8/scabbard-sample/src/main/java/dev/arunkumar/scabbard/App.kt#L10). The reason is, since it is a val, it will not be editable and also lazy being lazy means it will cached.
Notice the `DaggerAppComponent` class that did not exist before. This is a Dagger generated version of our `AppComponent` interface that is suitable for instantiation. This class holds the factory method we created before, and returns an instance of `AppComponent` that let's us access the dependencies we installed into the component. When we initialize our component, Dagger also intelligently creates all the dependencies in our graph. Now all that's left for us is to use the dependencies we declared in our app.
## Injecting dependencies