Angular 中的依赖注入
Dependency injection in Angular
依赖项是指某个类执行其功能所需的服务或对象。依赖项注入(DI)是一种设计模式,在这种设计模式中,类会从外部源请求依赖项而不是创建它们。
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 的 DI 框架会在实例化某个类时为其提供依赖。你可以使用 Angular DI 来提高应用程序的灵活性和模块化程度。
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
创建可注入服务
Creating an injectable service
要想在 src/app/heroes
目录下生成一个新的 HeroService
类,请使用下列 Angular CLI 命令。
To generate a new HeroService
class in the src/app/heroes
folder use the following Angular CLI command.
ng generate service heroes/hero
下列命令会创建默认的 HeroService
。
This command creates the following default HeroService
.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class HeroService {
constructor() { }
}
@Injectable()
装饰器会指定 Angular 可以在 DI 体系中使用此类。元数据 providedIn: 'root'
表示 HeroService
在整个应用程序中都是可见的。
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.
接下来,要获取英雄的模拟数据,请添加一个 getHeroes()
方法,该方法会从 mock.heroes.ts
中返回英雄。
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.
如果你确实要将组件和服务合并在同一个文件中,则必须先定义服务,再定义组件,这一点很重要。如果在服务之前定义组件,Angular 将返回运行时的空引用错误。
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
注入某些服务会使它们对组件可见。
Injecting services results in making them visible to a component.
要将依赖项注入组件的 constructor()
中,请提供具有此依赖项类型的构造函数参数。下面的示例在 HeroListComponent
的构造函数中指定了 HeroService
。heroService
的类型是 HeroService
。
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.
在其他服务中使用这些服务
Using services in other services
当某个服务依赖于另一个服务时,请遵循与注入组件相同的模式。在这里,HeroService
要依靠 Logger
服务来报告其活动。
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.
首先,导入 Logger
服务。接下来,通过在括号中指定 private logger: Logger
,来在 HeroService
的 constructor()
中注入 Logger
服务。
First, import the Logger
service. Next, inject the Logger
service in the HeroService
constructor()
by specifying private logger: Logger
within the parentheses.
当创建一个其 constructor()
带有参数的类时,请指定其类型和关于这些参数的元数据,以便 Angular 可以注入正确的服务。
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.
在这里,constructor()
指定了 Logger
的类型,并把 Logger
的实例存储在名叫 logger
的私有字段中。
Here, the constructor()
specifies a type of Logger
and stores the instance of Logger
in a private field called logger
.
下列代码具有 Logger
服务和两个版本的 HeroService
。HeroService
的第一个版本不依赖于 Logger
服务。修改后的第二个版本依赖于 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;
}
}
在这个例子中,getHeroes()
方法通过在获取英雄时通过 Logger
来记录一条消息。
In this example, the getHeroes()
method uses the Logger
service by logging a message when fetching heroes.