Android Dependency Injection - Manually Injecting Dependencies

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hi Everyone.   This is Belal Khan and you are  watching Simplified Coding.   Welcome to another video of  Android Dependency Injection course   and from this video, we will start implementing  the thing that we learned in the last video.   So in the last video, we discussed what actually  is Dependency Injection and how we can use this   technique in our kotlin codes and from this  video we will work in an actual Android project,   and here I have my project opened and this is the  code from one of the previous tutorial that is   Android login and signup tutorial  with MVVM architectural pattern.   So you can watch this course from here I will  give the link here and if you want the source   code of this project you can get it from the line  that is given in the description of this video.   So here you can see the project is opened and  this is the login fragment and if I run the app   it is working absolutely fine. So you can see I logged out   and I can even login like this. So I can login inside the application   and it is working absolutely fine. So I hope you know the basic application   architecture that is recommended for  Android and in this architecture first   we create a repository that communicates with  our backend API or local database and then we   create ViewModel and we observe the data from  ViewModel inside our fragment or activity.   So right now I am inside login fragment and  to create the ViewModel I need the repository   I need the local preference I need the API  and I also need the remote data source.   So all these things are the dependencies for  my login fragment and right now I am not using   any Dependency Injection in this project. So what is the drawback of coding like this?   So for example, I also need to create signup  fragment right now it is login fragment I also   need to create signup fragment and in signup  fragment as well I need all these things.   So what I need to do is I need to  copy and write the same code there   in signup fragment as well and that is not a  good idea because I am duplicating the code.   So later if I want to change something  I need to change every place.   So this is not a good approach and as we  discussed in the last video my login fragment is   constructing all else dependencies that should  not happen because all the dependency should   be given from outside the class and the class  should not construct its own dependencies.   So right now we will try to perform or use the  dependency injection technique in this project   but we will not use any third-party library that  is dagger or Hilt but first, we will try to do   the dependency injection manually in this project,  and then after doing it manually we will move to   the libraries like Hilt or dagger. So that we will understand   why exactly a library is needed. So what first I will do is I will create   a new package inside my main package and I  will name it di that means dependency injection   inside this package I will create a  class and I will name it AppContainer.   Now inside this class, I will  construct all the dependencies.   So what I will do is I will  copy everything from here   and I will paste everything here. Now we need context to construct   API and preferences. So what I will do is I will   pass context to AppContainer. So we have context here like this   and instead of require context, I will  pass the context here like this.   Now I will make all these things private because  I don't think I will need it outside the class.   So let's make everything private for now. Now one more thing is remaining   that is called ViewModel. Now ViewModel also we need in many places.   For example, I need this AuthViewModel  inside my signup fragment as well   and it is also a good idea to use a factory  pattern for these kinds of situations.   So for ViewModel, I will create a factory. So I will go to new and I will select kotlin   file class I need to do it again and I will  name it factory and I will create an interface   so that I can use the same interface  to create any type of ViewModel.   So I will write type as T because I want  to create as a generic type and now I will   create a function that is fun create and  it will create the ViewModel and it will   return T that will our ViewModel. Now I will create one more class   and I will name it AuthViewModelFactory. Now inside this class, I will inherit Factory and   from this class, I need to build AuthViewModel. So I will define it here like this   AuthViewModel and we will implement the  members we have to create function.   Now here we will return  AuthViewModel like this.   Now to create AuthViewModel we need authRepository  and this repository we will pass to the   constructor of AuthViewModelFactory. So here I will write private val   authRepository and repository and  here we can pass authRepository.   So we have the factory that will  construct our AuthViewModel.   Now I want to manage the dependencies  according to my applications flow and   right now the first flow that I  have in my application it is this   login or authentication flow. So I have this AuthActivity inside   this activity I have two fragments that will  require the authentication kind of dependencies.   So I will construct the dependencies  for authActivity and we will remove   all the dependencies from the memory  when the authActivity is destroyed.   So for this flow, I will create one more container  and I will name this container as AuthContainer   because it is for authentication flow. Now inside this AuthContainer I will define   val authViewModelFactory equals to  AuthViewModelFactory and for AuthViewModelFactory   we require the authRepository. So we will pass the authRepository to the   constructor of this class authContainer. So here I will define   authReository authRepository and now we can  pass this authRepository here like this.   So we have our AuthContainer. Now we will go to our AppContainer class   and here inside this class first we will  define val authContainer because this will   contain all the dependencies that are  required for authentication flow.   So here I will define authContainer of type  AuthContainer and I will make it nullable   and the initial value is null because I want this  dependencies only for the authentication flow.   So when the authentication flow started I  will initialised this AuthContainer and when   the authentication flow is finished I will  assign null again to this authContainer.   So let's do it. What I will is I will go to authActivity and   here I will define lateinit var appContainer. So we have the appContainer here.   Now to initialize the appContainer we can use the  application class that we already have here.   So we will go to class MyApplication and  inside this class, we will override the   function onCreate like this and here I will  create lateinit var appContainer like this   and inside the onCreate function I will write  appContainer equals to AppContainer and this   class requires a context so we can pass this  because we are inside application class.   So when our application is launched  the AppContainer is initialized.   Now come back to AppContainer and we  have this AuthContainer here inside our   AppContainer class and we need to initialse  this AuthContainer inside our AuthActivity.   Now let's do it.   So before setting the content view  I will initialize the AppContainer   not AppContainer actually the AuthContainer  that we have inside the AppContainer.   So here I will write appContainer  dot authContainer equals to   AuthContainer like this. Now this container requires   authRepository and we can get the  authRepository from our appContainer.   So here we can write appContainer dot we  need to make the repository public.   So this is the authRepository. So I will remove private from the authRepository   and now we can access it here. So we have authRepository like this.   We need to change this val to var because we  want to make it mutable so that we can reassign   the value for this authContainer. Now let's go back to authActivity.   Now here we have our appContainer  and we have initialise the   authContainer inside our appContainer. Now what we can do is we can override the   function onDestroy() and inside this function  what I can do is I can write appContainer   dot authContainer equals to null. So when this flow is finished we will remove the   container from the memory by assigning null. So that's it.   Now our container is ready and now we can  inject the dependencies using the Container.   So let's do it come to login fragment  and here I will delete everything.   Now this time to initialise ViewModel we  will use the appContainer that we created.   So here what I do is I will write require Activity  and I will cast it AuthActivity like this and   then I will write dot appContainer we will get  appContainer and from the appContainer we will   get authContainer and from the authContainer  we will get the ViewModelFactory.   So we will get authViewModelFactory from  here like this and from this factory,   we will create the view model like this. Now this authContainer is nullable.   So we need to add question mark here like this  and now we have our view model is ready.   Now I will change ViewModel to nullable  and the initial value is null like this   and here we need to add question mark. So I have added null safety everywhere   and that's it. Now we removed all   the code duplication and we are injecting the  view model with help of our appContainer.   So this is the manual approach  to doing dependency injection.   Now let's try running the application to see if  it working or not oops the application is crashing   and I think I miss something here. So let's check the authActivity   and yeah I forget to initialise  the appContainer here.   So what I will do is I will write  appContainer equals to application   as MyApplication that is MyApplication  class and then appContainer.   Now that's it should work now. Let's try again.   So you can see here that the application  is working absolutely fine.   Let's try login in.   So we are logged in and it is  working absolutely fine.   So what we did here is called  Manual Dependency Injection.   Now there are some problems with this approach.   The problem with this approach is we  need to manage the appContainer ourselves   as we are managing the appContainer we need  to create all dependencies manually by hand   and that is why we still have a lot of  BoillerPlate code in the project.   As you can see we are maintaining the dependency  graph manually for applications flow.   For example, in the current project  we created authContainer for auth   flow and we also removed authContainer from  memory when the auth flow is finished.   It is ok now but as the application grows it is  very difficult to optimize the dependencies and   it is very much possible that we will forget  releasing the dependency from memory.   So optimization here is very hard and  error-prone with this approach and finally,   the more you do things manually more  the chances are of making error.   So that's being said in the  next video we will start using   an automation framework for  dependency injection.   So that is all for this video friends I hope you  found this video helpful and learned something.   In case you have any question, problem or  confusion PLEASE leave it in the comment   section below and if you Like this video then  PLEASE hit on the Like button subscribe to my   channel if you are not already a subscriber and  PLEASE share this video with all your friends   learning Android Application Development. So that is all for this video friends. Thanks for watching this is Belal Khan now signing off.
Info
Channel: Simplified Coding
Views: 5,936
Rating: 4.9678717 out of 5
Keywords: android dependency injection, dependency injection android, dependency injection android kotlin, dependency injection android tutorial, dependency injection android medium, dependency injection android library, dependency injection android dagger 2, dependency injection android hilt, manual dependency injection android, dependency injection android beginners
Id: ouirnik2CPo
Channel Id: undefined
Length: 14min 53sec (893 seconds)
Published: Mon Apr 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.