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

简介: 在 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<boolean> {
    // returns true or false
    return this.http.post('/api/auth', { username, password });
  }
  getUsername(): Observable<string> {
    return this.http.post('/api/user');
  }
}

在 LoginComponent 里消费上述 Service 类的代码:

import { Component } from '@angular/core';
import { AuthService } from './auth.service';
@Component({
  selector: 'auth-login',
  template: `
    <button>
      Login
    </button>
  `
})
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: `
    <div>
      You are {{ username }}!
    </div>
  `
})
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 - 而无需进行进一步的更改。


这是因为 Angular 使用 AuthService 作为令牌来搜索我们的提供者。 由于我们已将其替换为新类 FacebookAuthService,因此我们所有的组件都将使用它。


相关文章
|
22天前
|
设计模式 Go
依赖注入实用指南:深入解析inject库
依赖注入实用指南:深入解析inject库
67 0
|
容器
Spring-AOP 自动创建代理之DefaultAdvisorAutoProxyCreator
Spring-AOP 自动创建代理之DefaultAdvisorAutoProxyCreator
89 0
|
前端开发 数据库 容器
AngularJS自定义服务(factory、service、provider)
AngularJS自定义服务(factory、service、provider)
|
存储
在 NgModule 里通过依赖注入的方式注册服务实例
在 NgModule 里通过依赖注入的方式注册服务实例
73 0
|
JavaScript 程序员
Angular 通过依赖注入机制注入一个对象的例子,什么是 ElementInjector
Angular 通过依赖注入机制注入一个对象的例子,什么是 ElementInjector
114 0
Angular 通过依赖注入机制注入一个对象的例子,什么是 ElementInjector
Angular 使用 Injector API 人工获取依赖注入的实例
Angular 使用 Injector API 人工获取依赖注入的实例
125 0
Angular 使用 Injector API 人工获取依赖注入的实例
Angular 依赖注入机制根据providers定义生成注入实例的框架代码
Angular 依赖注入机制根据providers定义生成注入实例的框架代码
Angular 依赖注入机制根据providers定义生成注入实例的框架代码
|
JavaScript
Angular 如何根据一个 class 的定义和数据,动态创建一个该类的实例
Angular 如何根据一个 class 的定义和数据,动态创建一个该类的实例
191 0
Angular 如何根据一个 class 的定义和数据,动态创建一个该类的实例
|
JavaScript 开发者
Angular 依赖注入学习笔记之工厂函数的用法
Angular 依赖注入学习笔记之工厂函数的用法
Angular 依赖注入学习笔记之工厂函数的用法
|
测试技术
对具有外部依赖的Angular服务类(service class)进行单元测试的几种方式
对具有外部依赖的Angular服务类(service class)进行单元测试的几种方式
128 0
对具有外部依赖的Angular服务类(service class)进行单元测试的几种方式