Dependencies Injection in Android – Part 1: Understand key concepts from your application

Tram Ho

Introduction

Hello friends. When programming Android, we all have our own design patterns for our team. One of the fairly familiar techniques we use with the MVVM design pattern is Dependencies Injection (DI). Many libraries exist to support DI such as Dagger, Hilt, Koin. I myself read a lot about these libraries in the early days but it was still very difficult to understand, so I returned to the starting point to find out what DI really is and we used to implement it like how. One of the articles going from the original concept is the Manual Dependencies Injection tutorial from Android Developers . Let’s take a look together.

What is Dependencies Injection?

I think in order to understand how DI is present in our Android projects, we should see it applied through the actual problem as follows:

  • We have an application with quite a few screens: Login, Register, Home, Setting … with model MVVM
  • The login flow has a LoginActivity as input, and we need a LoginViewModel object to handle the logic as well as the UI handle.
  • Assuming our screen needs the “Save username for next login” checkbox, we both need to request to the API as well as need to handle storage local (maybe Room can also just need SharedPreferences). Thus the LoginViewModel object needs 2 objects of UserLocalDataSource and of UserRemoteDataSource.
  • The UserRemoteDataSource that works with the API requires the Retrofit services object
  • To help LoginViewModel, we create a Repository class UserRepository to handle the handling with UserLocalDataSource and UserRemoteDataSource. And LoginViewModel will use this UserRepository object

Have you envisioned the dependence of one object on another yet?

UserRepository is responsible for working with local or remote source like this

Now the simplest way is to initialize it in LoginActivity and try it out

That is we are creating dependencies injection: dependencies of one instance on another, in the simplest way.

However, this approach is not highly recommended, because:

  1. We need to do a lot of work from top to bottom to initialize a viewmodel object that works with data. Sound not very convincing, right? Would you think that you are dependent on each other, you must declare in turn?
  2. If the Register screen also needs the userRepository instance, so that after the registration is completed, run the login stream, or the Setting screen to manage the user profile, then we must have 1,2,3,4 breath again to declare the time again. no turn yet?
  3. Then even if there is a management place that helps us to help us with the creation steps, it will be quite difficult to reuse this userRepository object on another screen, or use only 1 user info object for the whole. app set (is the design pattern singleton)

Manual Dependencies Injection: Creates a container to manage these dependencies

To solve too many steps to manually create the userRepository instance, let’s define a class that provides dependent objects (here are remoteDataSource and localDataSource) for creating that userRepository instance:

Now how to use this container for the whole app? We create a class MyApplication to support the provision of the container and declare it in AndroidManifest.xml

Then use it in the Login screen as follows

Okay, right, we didn’t have to go many steps to initialize loginViewModel.

Conclude

I hope the above is an example to help you understand Dependencies injection better in real projects. You will see it turns out we have been implementing DI all the time. In the next article, I will introduce ViewModelFactory and learn about scope management in Manual Dependencies injection.

Thank you for reading

Share the news now

Source : Viblo