When Angular was launched it came up with an intention of nice and cool feature called Dependency Injection and with that it has always been developer’s first choice on client side programming. It allows developers to inject dependencies in different components across our applications without need to know of how those dependencies are created or what sort of dependencies they need by themselves. Dependency injection is the ability to add the functionality of components at runtime. Earlier in dependency injection system of version Angular 1.x had some problems that which got resolved in Angular 2.x, which build the next generation framework.
In Angular 2 working of dependency is different from its predecessor i.e. 1.x. In Angular 2 dependencies are first registered in the collection of Providers using the methodology of collection of token-provider map. The Components gets command for the Dependencies to be injected in the constructor with the help of token. The injector thereafter searches for a provider in the Providers collection with the help of token. If the provider is able to locate it then it will instantiate and gets injected into the component.
What will happen if the provider is not found? Then the injector will pass on the request to the injector of the parent component. Now if the provider is located, then the request returns the instance of the Provider. If still it is not able to locate it then this process is going to be continues till the time the quest is complete and request reaches to the injector sitting at the top most level within the group of injector.
And in the event where failure continues to locate the service then that request throws back an error as shown below
"EXCEPTION: Error in Component class – inline template caused by No provider for Service!"
In this new version of Angular 2 it creates complete tree of injector & Providers which creates a similar appearance look alike the new Component Tree. And it is termed as hierarchical pattern.
Any Angular application basically is a set of components, directives and classes that often may or not be depends on each other. While each of the components can clearly instantiate each of its dependencies, Angular perform the duty for us by using its Dependency Injection(DI) mechanism.
But as a reader you should know that DI is an implementation to concept called IOC(Inversion of Control) so it becomes very much essential to get to know about IOC(Inversion of Control). There are also other implementation like Events and Delegate but in this article we will be discussing only on DI(Dependency Injection) as other implementation are beyond the scope of this article.
So it would be better if we first understand the concept(IOC) and then work in its implementation(DI) part.
IOC in simple words is a concept where general application flow is inverted. Logic which is not related to that class is given to external entity and then using it.
Still if above written line is not clear then let us understand using an example where we have "StudentClass" and student can be either boy or a girl and depending on that its entry will be done and then it will get added to the Students records. If the work of deciding student is boy or girl done by the "StudentClass" then it will get loaded. Instead of that how come this deciding part is done by external entity and that deciding factor next is passed to the "StudentClass" which will also reduce the load of it.
Below is the pictorial image showing the same where external entity is used for deciding factor and then it is injected into the "StudentClass" and finally it will proceed accordingly to finish its work. This is termed as IOC(Inversion of Control) where control is being inverted to the external entity.
Angular offers such a system that helps not only to register but also to instantiate component dependencies. In other words, DI supports in writing code in a loosely coupled manner and makes your code more easy to test and reusable. Using this way we will be more benefited with proper decoupled system and code part written would be much cleaner.
There are three types or levels on which Dependency Injection(DI) can be implemented
The DI in Angular 2 or Angular 4 basically consists of three things:
Injector - The object of the injector which exposes APIs to outside world in order to create instances of dependencies. Each of the Angular components has an "Injector" which is enough capable of injecting external entity as objects into other components. While working with any Angular application it is hosted by some root component, so there is always an availability of root injector in it. An injector very well knows how it has to inject one object of the specific type into the constructor of another.
Provider - A provider helps by telling the injector how to create an instance of a dependency. Provider with the help of token get maps that to a factory function which then creates an object instead. With the help of provider we can always map a typical custom type or a particular string to a concrete implementation of this type or a value.
Dependency - A dependency is such a type of which an object should be then get created. Newer version of Angular 2 provides a single API in order to do inject of services, directives, and different types of elements. Thereafter all of them get injected into the component’s constructor. With that as a result, there remains a very lesser API to learn resulting into simplification of testing of minimal components are much easier to test.
Hope that the theory of DI-IOC working with Angular is clearly understood by the readers. We have much more covered under the project series of Angular below is the first video of that series it is recommended for the readers who are new to Angular. With this video series a newbie can learn Angular practically while theory part running in parallel so that theory and practical goes hand-in-hand :-