Imagine you’re working at a Burger Junction and you need to make a burger. Before starting to work, you’ve already set up items that you’d need like buns, patties, sauces etc, so when you actually are going to make a burger you’ve everything that you need ready.
When we are building complex applications, we try to modularize the code so that it’s easy to read, understand and reuse if needed. This brings a challenge because a method might need an object of another class to execute. So now we have to make sure that before any method executes it has all the objects it depends on. This is where the concept of Dependency Injection comes into picture.
Dependency is nothing but an object and Injection is providing those objects wherever necessary. There are two roles in the DI system —
- Dependency Producer, class which is producing a object
- Dependency Consumer, class which is consuming the same object
Angular enables dependency injection using an abstraction called an Injector. A layer that connects producer and consumer is called an Injector. Whenever a dependency is requested, the injector checks to see if an instance of that dependency is available in the registry, if it is, it provides the instance to the consumer, if not, it creates the instance, stores it in the registry and provides it to the consumer.
In Angular, a dependency can be a service, a function or a constant such as a string. At the time of bootstrapping the application, Angular creates application-wide injectors (also called root-injectors) and any other injectors that might be needed.
Providing a Dependency
Let’s say, there’s a class called EmployeeService that needs to act as a dependency in a component.
@Injectable decorator tells us that this class can be injected. Dependency can be made available at 3 levels — @Component level, @NgModule level and Root level.
When we provide a service at the root level, Angular creates a single shared instance of EmployeeService and injects it into any class that might need it.
Injecting a dependency
The most common way to inject a dependency is to declare it in a class constructor. Hence, whenever angular creates a new instance of the component, it determines which dependencies needs to be injected based on the constructor’s parameters.
Reference — https://angular.io/