在|在 NgModule 里通过依赖注入的方式注册服务实例

下面是在 NgModule 中注册一个 service 的典型例子。

import { NgModule } from '@angular/core'; import { AuthService } from './auth.service'; @NgModule({ providers: [AuthService], }) class ExampleModule {}

上面的代码,因为 provide 和 useClass 属性值都相同,所以其实是简写形式(shorthand),完整的写法:
import { NgModule } from '@angular/core'; import { AuthService } from './auth.service'; @NgModule({ providers: [ { provide: AuthService, useClass: AuthService, }, ], }) class ExampleModule {}

对象中的 provide 属性是我们正在注册的提供者的令牌。 这意味着 Angular 可以使用 useClass 值查找 AuthService 令牌下存储的内容。
Angular 依赖注入为应用程序开发提供了许多好处。 首先,我们现在可以拥有两个具有完全相同类名的 providers,Angular 在解析正确的服务时不会有任何问题。 其次,我们还可以使用不同的提供者覆盖现有提供者,同时保持令牌相同。
原始的 AuthService 类的实现:
import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; @Injectable() export class AuthService {constructor(private http: Http) {}authenticateUser(username: string, password: string): Observable { // returns true or false return this.http.post('/api/auth', { username, password }); }getUsername(): Observable { return this.http.post('/api/user'); }}

在 LoginComponent 里消费上述 Service 类的代码:
import { Component } from '@angular/core'; import { AuthService } from './auth.service'; @Component({ selector: 'auth-login', template: ` ` }) export class LoginComponent {constructor(private authService: AuthService) {}login() { this.authService .authenticateUser('toddmotto', 'straightouttacompton') .subscribe((status: boolean) => { // do something if the user has logged in }); }}

在 UserInfoComponent 里使用这个 Service class:
@Component({ selector: 'user-info', template: `You are {{ username }}!` }) class UserInfoComponent implements OnInit {username: string; constructor(private authService: AuthService) {}ngOnInit() { this.authService .getUsername() .subscribe((username: string) => this.username = username); }}

把两个 Component Class 和一个 Service class 封装到一个 NgModule 里:
import { NgModule } from '@angular/core'; import { AuthService } from './auth.service'; import { LoginComponent } from './login.component'; import { UserInfoComponent } from './user-info.component'; @NgModule({ declarations: [LoginComponent, UserInfoComponent], providers: [AuthService], }) export class AuthModule {}

也可能存在其他组件使用相同的 AuthService。 现在假设有一个新的需求,需要将我们的登录身份验证方式,更改为一个使用 Facebook 登录用户的库。
最笨的办法是遍历每一个组件实现,并更改所有导入以指向这个新的提供者,但是我们可以利用依赖注入,轻松覆盖我们的 AuthService 以使用 FacebookAuthService:
import { NgModule } from '@angular/core'; // totally made up import { FacebookAuthService } from '@facebook/angular'; import { AuthService } from './auth.service'; import { LoginComponent } from './login.component'; import { UserInfoComponent } from './user-info.component'; @NgModule({ declarations: [LoginComponent, UserInfoComponent], providers: [ { provide: AuthService, useClass: FacebookAuthService, }, ], }) export class AuthModule {}

上面的例子用不同的值替换了 useClass 属性。 这样,我们可以在我们的应用程序中的任何地方使用 AuthService - 而无需进行进一步的更改。
【在|在 NgModule 里通过依赖注入的方式注册服务实例】这是因为 Angular 使用 AuthService 作为令牌来搜索我们的提供者。 由于我们已将其替换为新类 FacebookAuthService,因此我们所有的组件都将使用它。

    推荐阅读