Hey, in this video, we'll discuss
about provider or services in nest.js, what is dependency injection, and
what all scope nest.js provides us while doing the dependence injection. We
are going to see all that in this video. Hi everyone, this is Subrat, and you are
watching Fun Of Heuristic. So on this channel, we make videos like this which are related
to programming and web development, so please consider subscribing and
hit the bell icon if you haven't yet. So, what is a provider? A provider, as the name
says, provides some functionality to some other things. Like it provides functionality
to your controller. In the sense of Nest, it provides functionality to other
providers or services. That's why the name is provider. In Nest, we call it
services, similar to Angular. Similarly, Nest also has services or providers which are also
injectable. The scope of the provider is a little different in Nest and in Angular. If you are not
from Angular and don't know anything about it, think like the service or a provider in
Nest is just a place where you can write your business logic. That provider
can be injected in multiple places. We'll go to the code now. In our last video, we
discussed controllers. If you haven't watched that video or don't know what a controller
is, please go ahead and watch that video. I will link them in the card. Here, if you see in
our controller, we are using our app service. App service is a provider or a service which we
provide to different modules. It's just a class which gives you the ability to do business logic.
To create a provider or service, like Angular, Nest gives us a command: Nest generate
service. So, G for Generate, S for service, and you can write car. For now, I'm just writing
car to create a folder with the service and the spec file in it. So, if you go here, you have
a car service. It's just an injectable file, and we have a spec for it. This car service
is now provided inside our app module. This car service can be used in multiple modules. In
those scenarios, our scopes come into the picture. Before explaining scope, I'd like to explain what
is dependency injection. When you pass something in the constructor, in the background,
it's injected to your app controller. Before it's injected, what happens is when you
start your application, your app scans through all the injectable decorators. If it finds it,
it registers them and creates an instance of it according to the scope. By default, the scope is
default. We have three scopes, and I'm going to explain. By default, it's Singleton, which means
only one instance of your app service will be created. So, in this scenario, when we have
created a car service, whenever we start our application, only one instance will be created.
We can pass that instance to various modules. Here we have only one module, but you can pass
this instance to various modules, and the same object will be passed across your application.
That's the default scope of injection in Nest. Now, we'll see what is dependency injection.
Here, I have three boxes which represent three modules. We'll create one box which
represents our services, let's suppose S1, and another box here which will represent
our service too. First of all, dependency injection is a pattern which comes from inversion
of control. If you want to know more about them, I will link some articles or blog posts in the
description below. Think like you are segregating your dependencies from your controller, in
our scenario, controller and services. Now, your controller is not much dependent
on the business logic happening inside your services. What you are doing is you
are just injecting them, calling it, and hoping that method will do its work and return
the result you want. From a controller point of view, your application is decoupled. Your
controller can have multiple services injected, and that can do multiple calls and send
data to your client as per the requirement. Coming back to dependency injections and
the scopes Nest provides, by default, Nest injection is Singleton. When we start our
application, a virtual memory will be created, and here S1 and S2 will be registered as a
Singleton instance. If your module is eagerly loaded, that means for this kind of scenario, you
are loading the module eagerly, on the start of the application itself, and you are providing
your services eagerly also. That means your module will be provided by S1 or S2. Suppose
these two modules are eagerly loaded. Suppose we are loading this module lazily. Whenever it
comes, and whenever you want to load this module, then it will get the same instance as these two
modules got. Suppose you have instantiated some variable inside it and you have changed it with
some operations or some time-bound operation, or sometimes you are adding it, or something which
needs to be passed across the module, then this service will help you. Because by default,
your injection will happen as a Singleton, and that's why a single instance
will be passed to all the modules. As we are discussing Singleton, if you go
to our code, for example, car service here, you can pass scope. Nest provides us three
scopes: the default one, which we just saw, Singleton throughout the whole application;
the second one is request; and the third one is transient. If you go for request scope,
then what will happen, what will change in this scenario, is the creation of this green box, the
creation of your object. What the request scope means here is whenever you get a request from
your client, maybe a GET call from a browser, then at that time, this will be
created. For each request, and for the whole request-response cycle, a single
instance will be passed to all your modules. That's the basic difference between
a Singleton and a request scope. Now, we'll see what the scope transient
means. If you change this to transient, each private instance will be created.
That means it doesn't care about the user, it doesn't care about a request. For a
scenario, inside this module, you have, suppose, three controllers. In this controller,
you are injecting or instantiating your services. For example, from this controller, suppose this
is C1, from C1 we are instantiating or injecting our service one, which has this scope transient.
For that, whenever your controller will be loaded, it will call your service, and at that time,
one service instance will be created, like S1, and it will be assigned to a controller.
Suppose your controller 2, C2, is using S1, it will have a separate S1 service. That means
whenever it gets instantiated or whenever it gets called, a new instance will be created.
These are the three scopes that Nest provides. But if you are not sure, and you should
use the request scope or a transient scope, if you don't have a solid scenario that you
should use a request or a transient scope, then you should not add any scope at all. Or you can
add scope as default, but it doesn't make sense. Now, we'll see what are the ways we can
inject our services to our controller or to other services. Here, as you can see,
you have a private readonly app service. We have injected through a constructor. But it's
also possible to inject through your property, as a property. For example, car service,
and for this, you need to keep @Inject. It's from Nest common, and this will inject
your car service to your app controller. Now, suppose you don't need app service, or
you can also do the same for app service, and you don't want a constructor injection. It's
debatable which one is good. Some say constructor injection is good, some say property injection is
good. It depends on you. What happens behind the scenes is similar. You already have an instance of
your service, you are just getting an instance of that being injected to your controller, so in this
case, controller. Suppose you are adding the same in a service, and if I go and add it here,
then it will also work. Now, I can access my car service. That's how easy it is to access
or to inject a service in your Nest application. Nest also provides us with an optional injection
for your service. What is optional and why it provides a separate parameter? Suppose in
this scenario, whenever our app controller will be created, our app service needs to be
resolved. That means your instance of your app service should be available, it should not
be null, else it will throw you an error. But if you pass an optional parameter, it
is optional now. So if your app service has not been instantiated yet, or you will decide in
runtime, then you can pass an optional parameter here. You can also create a custom service to
do some custom tasks, and that we'll see in our future videos. If you know Angular, then here also
we have useValues, useFactories, and useClasses. We're going to cover all in our future videos,
and those will be helpful in multiple scenarios. So please do subscribe to the channel
so that you will not miss those videos. That's all for today. Today we saw what is
a service, or what is a provider, what is dependency injection, and how Nest handles it by
providing different scopes, and how you can inject your services to your controller or to different
other services by using constructor injection or property injection. Please hit the like button
if you liked the video. Till now, please do subscribe to the channel and don't forget to hit
the bell icon so that you will not miss future videos. Please do share this video among your
friends, family, colleague, and let them know how they can use the services. We'll meet in
the next video. Till then, stay happy. Bye-bye.