Android MVP architecture with Dependency Injection
Design pattern is an addictive topic which will never feed our curiosity enough, because of its beauty in software development.
My last post covered the importance of a proper architecture pattern and the introduction of MVP in Android projects. In this article, we are going to leverage our codes by using another design pattern: Dependency Injection.
What is Dependency Injection?
Well, Dependency Injection is a design pattern which is originally mentioned in Martin Fowler’s article. It allows developers to write code that has low coupling and which can therefore be easily tested.
Dependency Injection is a really huge topic in software development, so we are not going to cover the whole stuffs about it.
Instead, we are going to see how it works with and complements to MVP architecture in Android project. This is our main focus in this article.
Why do we need Dependency Injection?
As we pointed out that a good architecture makes our apps easy to test and easy to maintain. Dependency Injection also favors this goal. It improves testability and reduce maintenance cost of our ‘pure’ MVP apps.
Let’s review the View and the Presenter of the previous MVP example in the last article.
A class should not initiate a dependency by itself because it creates a high coupling that will be quite difficult to test. However, in my above codes, the Presenter creates a Model instance inside its constructor, and the View creates a Presenter instance inside its method.
How can I use a mock instance of the Model or the Presenter for testing? Sorry, no way. :|
The solution is that these dependency objects should be “injected” from outside components like factories or builders.
How does Dependency Injection work with MVP in Android?
To apply Dependency Injection, we can simply understand the pattern and follow its rules to implement it. However, we will struggle with a problem that we will have to write a lot of boilerplate codes and maintain them.
Fortunately, there is an powerful open-source framework called Dagger out there to support us. It is developed and maintained mainly by engineers from Square and Google. You can find its version 1(deprecated) and version 2 on Github.
You can setup Dagger in your Android project by following its installation guide on Github page. Let’s see how we apply it.
As mentioned above about MVP sample, we will inject dependencies objects from outside instead of initiating inside the classes. Here is how the code is updated:
In above codes, I used “@Inject” annotation which is one of fundamental annotations of Dagger. In compiling process, Dagger will look at all of these annotations to create exact dependency objects for you. It sounds amazing, right. It is cool but not a magic tool because it is not enough.
You have to tell Dagger that where and how to get these necessary dependencies. That is the reason why you need two other important guys.
- Module: A class provides dependency object, and you need to define it by using “@Module” annotation to help Dagger know where to find the dependencies.
- Component: “@Inject” and “@Module” classes are established but don’t know each other. So, the component class is a bridge to bring them to work together. And, you need to define it by using “@Component” annotation.
Finally, let’s build them by calling this (in this case, it is inside Activity class).
We have completed all main steps. For more details, you can visit this Github repository and then checkout “dagger” branch.