Hi Everyone.
This is Belal Khan and you are watching Simplified Coding.
In the last video, we learn about basics of Dagger framework and in this video, we will
finally implement Dagger in our current project. So in this video, we will learn how we
can perform dependency injection using Dagger2 framework in our Android project.
So this is the current project that the we are working on and we have already implemented
the manual di approach in this project but as we want to implement
Dagger in this project.
So first we will remove the manual di codes.
So this was the di package that we created.
So I will remove both the
classes inside the di package.
So let's delete anyway and the inside
myApplication I will delete everything and one more thing that we need to do is we need to
go inside login fragment and we will remove this line to create ViewModel and inside AuthActivity
as well we will delete the AppContainer thing. So let's delete everything.
So we have deleted all the manual codes from this project and now we want
to use Dagger2 for Dependency Injection. So the first thing we need to do is we
need to add Dagger dependencies and we will do it inside the build dot gradle
file app level build dot gradle file.
So open this file and we need to
add Dagger dependencies here.
So these are the Dagger dependencies you need to
add these lines in your app level builddot gradle file and you can get the source code from the link
that is given in the description of this video.
So you can copies these dependencies from
there or you can visit the official Dagger website to get the dependencies I will leave
the link of the description of this video.
So we have added Dagger2 dependencies
and now let's sync the project.
Once you have added Dagger dependencies
you can perform dependency injection.
So now I will do it I will perform dependency
injection inside my login fragment and here I need to inject ViewModel inside this fragment.
So let's open the ViewModel class that is AuthViewModel.
So whenever you want Dagger2 construct or build a dependency you need
to tell Dagger that Hey you have to build this instance and to do this you can use the Inject
annotation as I told you in the last video.
So what I will do here is I
will write (at the rate)@Inject and then I will write constructor.
Now Dagger knows that I have to build AuthViewModel but to build AuthViewModel we need
this AuthRepository and right now Dagger do not know that how to build this AuthRepository.
So again we will open this AuthRepository and again we have to tell Dagger that
you have to build this as well.
So again we will do the same thing I will
write here Inject and then constructor.
Now again Dagger knows that it has to build
AuthRepository but Dagger do not know that how to build this AuthApi and UserPreferences.
Now AuthApi here is an interface that cannot be constructor injected because we cannot directly
instantiate an interface and the same thing applies with UserPreferences because this class
requires context and we cannot just initialize context like any other class like we cannot
write new context or context than parenthesis.
So we cannot initialize context like that and that
is why it is not possible to constructor Inject, the interface, or this UserPerferences, and when
you come to situations like this you need to create a module that will construct the dependency
that are not possible to constructor inject.
So inside my di package, I
will create an AppModule.
So I will name it AppModule and it is a normal
class and we need to annotate this class as module because it is a module.
So this is my AppModule.
Now inside my AppModule, I need to
build AuthApi and UserPreferences.
Now to build AuthApi I want my retrofit instance
that I have defined inside remoteDataSource.
Now, this class can be constructor injected
because we can initialize this class as we initialize any other normal class.
So here I can simply write Inject constructor and now we can inject this class but
this AuthApi we cannot instantiate it like that.
So what we will do is we will
build the instance of AuthApi.
So let's go back to our AppModule
and here we will build the AuthApi.
So here I will write singleton I want the Api to
be singleton and I will write provides we need to use these annotations to provide the dependency.
Now I will create a function let's say I will write fun provideAuthApi like this and to
provide AuthApi I need my remoteDataSource.
So here I will define
remoteDataSource remoteDataSource.
Now this remoteDataSource
can be constructor injected.
So I will get here because
this will be injected here.
So here I will use
remoteDataSource to build AuthApi.
So here I will write return remoteDataSource dot
buildApi and we will pass AuthApi like this.
We need to import AuthApi
and then class dot java.
Now the second parameter that is
required is context and we can pass the context to this AppModule constructor.
So here I will write private val context Context and we can use the context here like this and let's define the return type that is AuthApi.
So we have the function ready that will give us the AuthApi the same way I will define one more
function that will give us the user preferences.
So we have provides and we will
write fun provideUserPreferences and we will write return UserPreferences
like this and we will pass the context and add the return type.
So now we have both the instances that we need to construct our AuthRepository.
So let's come back to AuthRepository where it is it is inside the repository package and now
we have the AuthApi and we also have the UserPreferences and now we
can inject AuthRepository.
So now the Dagger knows how to build
AuthViewModel how to build AuthRepository and how to build AuthApi and UserPreferences
and now we can simply inject the required things into our fragment or activity.
So we have created AppModule.
Now after creating AppModule
one more thing we need is we need an injector that will actually inject the
dependencies inside our activities and fragments.
So we will create one more class here.
So I will name it LoginFragmentModule.
Now, this will be an abstract class and
we will annotate it with Module again because this is a module.
Now inside this class we will define a function that will provide the
injector and we need to annotate this function as (at the rate)@ContributesAndroidInjector and
we can name the function anything I will write contributeLoginFragmentInjector and the return
type will be your fragment class in my case it is LoginFragment like this and it is an
abstract function.
So we have the injector function
that will provide the injector.
Now after this we can finally create
our AppComponent or application graph.
So we will create one more file and
this time it will be an interface.
So I will create new interface and I will name it AppComponent or you can name
it anything that you want. So this is AppComponent it will be an interface
and you have to annotate this interface as (at the rate)@component because this is your
application component and we will also define that the module we have for our AppComponent.
So I will define module like this. We will provide an array and we
will define all the modules.
So We have created two modules here you can see
we have created AppModule and LoginFragmentModule and one module is a pre-defined
module that we need to pass here.
So first I will pass that pre-defined
module and it is AndroidInjectionModule.
So we will pass this module then we will
pass LoginFragmentModule and then we will pass AppModule and all the modules that you will
create you have to define it here like this.
Finally, inside our interface, we will create
a function that will perform the injection.
So I will define here fun Inject and I will pass
here our custom activity class instance here in my case it is MyApplication.
So I will write here an application MyApplication like this.
Now after writing all these things you can rebuild your project.
So go to build and rebuild the project. After rebuilding the final thing that
we need to do is we need to come inside our application class and inside this class
first, we will implement HasAndroidInjector.
So we will use this interface
that is HasAndroidInjector and as we implemented an interface we
need to override or implement members.
So we will implement the function that is
AndroidInjector and to return an AndroidInjector we will inject the AndroidInjector inside our
MyApplication class and to inject anything we need to use (at the rate)@Inject annotation.
So I will write Inject and we will write a lateinit var here and
it will be DispatchingAndroidInjector.
So this will be the type.
So this is the thing that we will be used DispatchingAndroidInjector and the type will be
Any and we can return this mInjector from this override fun androidInjector.
So here we will write return mInjector.
Now finally to inject this mInjector
inside this MyApplication class we need to override the onCreate function.
Now inside onCreate function I will call DaggerAppComponent.
Now, this class is a generated class and whatever interface you will create for
your component in my case it is AppComponent.
So dagger plus your AppComponent interface name.
So in my case, it is DaggerAppComponent. Now from this class, we will
call the builder function and after builder, we will add
our AppModule that we created.
So whatever the AppModule you will create in my
case I have created only one module as you can see you may ask that we also have loginFragmentModule
but this is an abstract class and it will be generated automatically but in case of this
AppModule class we need to provide an instance because this is not an abstract class and we have
to provide the instance of this class manually.
So come back to MyApplication
and here we will call AppModule function from this builder instance.
So we will call AppModule and we will pass AppModule and for the context, we can pass this
and then finally we will call the build function to build our DaggerAppComponent and after this
build function we will call the Inject function and for our application
instance, we can pass this.
Now calling this function means we
are injecting all the dependencies.
So in our My Application class, we need this
mInjector dependency and we are injecting it here by calling this Inject function.
So that's all for MyApplication class and our Dagger setup is done and now we can
simply inject the required dependencies.
For example, in my LoginFragment
let's come back to LoginFragment here I want to inject my ViewModel.
So I can simply write here Inject lateinit var viewModel and that's it.
I need to define a type.
So it is AuthViewModel and the
ViewModel is injected in my fragment.
So this is how we can inject dependencies
inside our fragments or activities but to provide the dependency we need to call one
more function that is the inject function and we will do it inside our onAttach function.
so we will override the onAttach function and inside this function, we will
call AndroidSupportInjection.
In case of fragments you need to write AndroidSupportInjection dot inject and you
will pass this like this and the dependencies are satisfied now that means this viewModel
is injected inside this fragment.
So let's try running the application
and see whether it is working or not.
So as you can see as we are getting an error
because I have missed a very small thing.
So I will go inside my AppComponent and as you
can see here the error is saying like unscoped may not reference scoped bindings and that is why
I need to define a scope for my AppComponent.
So here I will define singleton like this
and now let's run the application again. So here you can see our application
is working absolutely fine that means our ViewModel is successfully
injected inside our fragment. So let's try login in I will enter my
email and password and I will press login and you can see we are inside the application that
means our application is working absolutely fine and the ViewModel is successfully injected. So that is all for this video friends and
I think one more thing I need to tell you and that is how to inject
things inside activities. So it is very simple you just need to create one more module for your activity and
this time it will return your activity. For example, I will create one
module for my AuthActivity. So let's say I will create
AuthActivityModule like this and it is module and this time it
will return AuthActivity like this that's it, that's all we need to do and we also
need to add this module to our AppComponent. So here we will add AuthActivityModule like this
that's it and after this, we will go to activity. Let's go to AuthActivity and here we can do the
same thing to inject dependencies we will write Inject let's say I want to inject the same
ViewModel and lateinit var and ViewModel like this and the ViewModel is injected just to satisfy
this dependency what I need to do I need to call AndroidInjection dot inject like this and we need to do this thing before the
super dot onCreate remember this thing. So this is how we can inject things
inside our activities as well. Now before wrapping of this video, I
will summarize the steps for you that how you can perform or use dagger for
dependency injection in your project. So the first step is you need
to add Inject annotations. So add Inject annotations to
classes that you want to inject. So this is the first step. After this what you will do
is you will create a module. So create a module for the classes that
cannot be constructor injected like this. For example, an interface that
cannot be constructor injected. Now step three is create injectors
for activity or fragments. And the fourth step is create AppComponent. And the fifth step is instantiate
Dagger inside your application class and you also need to implement HasAnroidInjector
implement HasAnroidInjector and inject what was that I forget the name so it
was the DispatchingAndroidInjector. So let's come back to our AuthActivity. So we will instantiate Dagger inside application
class, we will implement HasAnroidInjector and we will inject DispatchingAndroidInjector
and finally use AndroidInjection dot inject to inject dependencies with
the help of Inject Annotation. So these are the steps that you need to follow
for injecting dependencies using Dagger2. So that is all for these video friends I hope you
found this video helpful and learned something new in case you did then PLEASE hit
on that Like button subscribe to my channel if you are not already a subscriber and you can share this video with all your
friends learning Android application development. So thanks for watching everyone
this is Belal Khan now signing off.