Dependencies are services or objects that a class needs to perform its function. Dependency injection, or DI, is a design pattern in which a class requests dependencies from external sources rather than creating them.
Angular's DI framework provides dependencies to a class upon instantiation. You can use Angular DI to increase flexibility and modularity in your applications.
See the live example for a working example containing the code snippets in this guide.
To generate a new HeroService
class in the src/app/heroes
folder use the following Angular CLI command.
ng generate service heroes/hero
This command creates the following default HeroService
.
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class HeroService { constructor() { } }
The @Injectable()
decorator specifies that Angular can use this class in the DI system. The metadata, providedIn: 'root'
, means that the HeroService
is visible throughout the application.
Next, to get the hero mock data, add a getHeroes()
method that returns the heroes from mock.heroes.ts
.
import { Injectable } from '@angular/core'; import { HEROES } from './mock-heroes'; @Injectable({ // declares that this service should be created // by the root application injector. providedIn: 'root', }) export class HeroService { getHeroes() { return HEROES; } }
For clarity and maintainability, it is recommended that you define components and services in separate files.
If you do combine a component and service in the same file, it is important to define the service first, and then the component. If you define the component before the service, Angular returns a run-time null reference error.
Injecting services results in making them visible to a component.
To inject a dependency in a component's constructor()
, supply a constructor argument with the dependency type. The following example specifies the HeroService
in the HeroListComponent
constructor. The type of heroService
is HeroService
.
constructor(heroService: HeroService)
For more information, see Providing dependencies in modules and Hierarchical injectors.
When a service depends on another service, follow the same pattern as injecting into a component. In the following example HeroService
depends on a Logger
service to report its activities.
First, import the Logger
service. Next, inject the Logger
service in the HeroService
constructor()
by specifying private logger: Logger
within the parentheses.
When you create a class whose constructor()
has parameters, specify the type and metadata about those parameters so that Angular can inject the correct service.
Here, the constructor()
specifies a type of Logger
and stores the instance of Logger
in a private field called logger
.
The following code tabs feature the Logger
service and two versions of HeroService
. The first version of HeroService
does not depend on the Logger
service. The revised second version does depend on Logger
service.
import { Injectable } from '@angular/core'; import { HEROES } from './mock-heroes'; import { Logger } from '../logger.service'; @Injectable({ providedIn: 'root', }) export class HeroService { constructor(private logger: Logger) { } getHeroes() { this.logger.log('Getting heroes ...'); return HEROES; } }
import { Injectable } from '@angular/core'; import { HEROES } from './mock-heroes'; @Injectable({ providedIn: 'root', }) export class HeroService { getHeroes() { return HEROES; } }
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class Logger { logs: string[] = []; // capture logs for testing log(message: string) { this.logs.push(message); console.log(message); } }
In this example, the getHeroes()
method uses the Logger
service by logging a message when fetching heroes.
© 2010–2021 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://v11.angular.io/guide/dependency-injection