3.2 Dependency Injection
It's important to have a good understanding of Angular's dependency injection system, so in this lesson we'll see how to inject the service we created into one of our components.
1.Introduction6 lessons, 42:00
2.Get Started With Angular7 lessons, 42:38
3.Core Concepts7 lessons, 55:20
4.Template Deep Dive11 lessons, 1:10:56
5.Forms10 lessons, 1:45:41
6.Routing9 lessons, 1:15:10
7.Using the HTTP Client5 lessons, 56:24
8.Testing10 lessons, 1:23:27
9.Building for Production1 lesson, 03:40
10.Conclusion1 lesson, 01:32
3.2 Dependency Injection
Hi, folks. In this lesson, we're going to take a look at how dependency injection works in Angular. Dependency injection was a feature of the original Angular JS but it's a little different in modern Angular. So it's perhaps worth spending a little time getting familiar with it, let's take a look. Dependency injection is a common pattern in software development that decouples classes from their dependencies. Instead of a class instantiating its on dependencies, which would mean that if those dependencies changed in some way, the class that instantiates them would also probably need to change as well, the dependencies are instantiated and then injected instead. Earlier on we created an injectable constants class, so let's inject this into our stack component. This is a two-step process, we first need to register our service with a provider and then we can actually inject the service. We can register the constant service with a provider for our application module. And that will mean that the service is available to use throughout the application. And that's exactly what we want in this case. Let's open up the app.module.ts file. In the configuration object passed to the NG module decorator, there is an empty providers array. This is what we need to use register our service. We just need to import the service into this file. And once we've imported it, we can then pass it to the providers array. So this will now create a provider for our constant service. During Angular's bootstrapping process, one of the things it does is create injectors so that dependencies can be injected in various places throughout the application. It always creates a route injector and any provider's registered in a module are added to this route injector. If we had multiple modules, all of their provider's would be registered with the route injector. In this case we only have a single module and a single provider, but nevertheless our service is now registered. And we are free to inject or enter any component within this module. Which all of our application will be within this module. So that means we'll be able to use it throughout the application. So let's open up the start.component.ts file. And we need to import our service into this file as well. And we use the constructor of the class to inject our service. The constance parameter passed to the constrictor is of the type constant service, which is the type that's exported by the service itself. So we can see that the class exports itself as a constant service, and this is what gets imported here, and it's the type specified after the constant's property. So the parameter where we inject the service into the constructor has the public accessibility modifier at the start. And this actually enables a really useful type script feature called parameter properties. So when we use any of the access modifiers for a constructor parameter including private or protected, or in this case public. TypeScript will automatically create a matching property for us on the class instance and assign the value of that parameter to the property. So this saves us having to type some boilerplate code in our classes. So if you remember when we were working on the service, we had to add these properties here. We don't need to do that when we inject into the constructor. That's what TypeScript will do for us. So now anywhere in our class, we can make use of the constant service and we can easily get a hold of one of the constants. And let's go back to the browser now. And we'll open up the console. And we can see our constant service has been locked. So behind the scenes, Angular has instantiated our service and injected an instance of it into our component. Because we added the provider for this service to the NG module for the app, the provider is registered with the root injector. And we can then inject it into any component within our application. Angular will instantiate the class as a singleton. So there will only ever be one instance of the service which is necessary if we want to share data between different components. As we are registering providers with the root injector, we can also register service providers with individual components. So if we wanted to inject the service directly into the start component but not have it available throughout the entire module, we could do this instead. This would give us a new instance just for this particular component. So in our case that wouldn't be terribly useful tool because we do want to share this service between a number of components, but if we didn't want to do that and we had a service that was just for a particular component, then we can use the provider's array with the component decorator just like we used it with the module decorator. We're not going to do that, that was just an example so I'm just going to go back and delete this now. And we also don't want to log the service to the console, so I'm just gonna remove the log now from the ngOnInit as well. But we'll still inject the service into the component, because we will be making use of it. So in this lesson, we learned a little bit about how dependency injection works in Angular. We saw that we can use providers to register our services with either the root's injector or a component injector. We saw that the root injector makes the service globally available to any component within that module. But the component injectors are better suited to services that only need to be injected into a single component or its descendants. Once the service has been registered, we can then inject it into the constructor or the component. And if we make use of TypeScript's parameter properties feature, it will add the instance properties to the the component for us so that we don't have to do this manually. Thanks for watching.