Join G. Blake Meike for an in-depth discussion in this video What is Dagger?, part of Android Dependency Injection with Dagger 2 and Kotlin.
- [Instructor] So before we dig into using Dagger, let's review some basics. So, first question. What's Dagger? Well, Dagger is an extension to the Kotlin compiler. It autogenerates source code that is then compiled into your application. The code that Dagger generates implements dependency injection for objects in your application. Dependency injection is sometimes called inversion of control. Let's dig a little deeper into this. What do I mean when I say Dagger is a compiler extension? Well, as Kotlin compiles your code the Dagger extension examines it for certain annotations.
Dagger generates additional source code based on the annotations that it sees. That code is then also compiled into your application. Most of Dagger is actually gone once the code is compiled. You can think of the code that Dagger generates as sort of a third party library that is very specialized for your application. Second, Dagger is a dependency injection framework. What do those words even mean? Well, dependency happens when one thing can't function without the help of another.
In this bit of code for instance, MainActivity has a dependency on MainPresenter. The activity requires the presenter in order to function. Injection is just a fancy way of saying provides an instance of. In this code the method, set presenter, injects a MainPresenter into the MainActivity. It provides the MainActivity with the MainPresenter on which it depends. A method is only one way of providing an object with the objects on which it depends.
There are several others. The simplest way for an object to obtain its dependencies is for it to create them. As an example, consider a NetworkClient that depends on a network connection. The network could be connected to one of two possible end points. One for the debug release and one for the production release. Here's a naive implementation of the client. This client has two problems. It has to know whether the application is in debug mode or not. That means it has to import build config.
It also means that the code that checks build config debug will have to be duplicated in each client. Second of all though, it can't be tested without a real network. Because the client creates the instance of network impl, there's no way to replace that instance with a mock. We can do way better than that. In this improved version, the client get its dependency, a network connection, from a factory. This is a big improvement for several reasons.
The logic that determines whether the application is in debug mode or not is now centralized in the factory that creates the connection. Second, the factory can return any object that implements network connection. For unit tests, it could return a mock. We could do even better than this though. In this version, the client is injected with its dependencies in its constructor. This is awesome because the client has no idea where the network connection came from.
It can be any implementation of network connection. It would be completely trivial to pass a mock to this client during testing. Also, the client is complete and ready to use as soon as it is constructed. There is no time during which the object exists but cannot be used because it does not have its dependencies. The code that Dagger generates supports dependency injection for annotated objects in your code. In this video I've introduced Dagger, an extension to the Kotlin compiler that supports dependency injection and explained why you might want to use it in your code.
In the next video, we'll have a closer look at how Dagger actually implements dependency injection.
- Dagger basics
- Method and field injection
- Lazy and provider injection
- Dagger annotations: @Module, @Binds, @Provides, and @Named
- Components and subcomponents
- Singletons and custom scope