关键词搜索

源码搜索 ×
×

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

发布2022-07-18浏览343次

详情内容

下面是在 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 {}
    
      9
    • 10
    • 11
    • 12
    • 13

    对象中的 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');
      }
    
    }
    
    
      9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在 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
          });
      }
    
    }
    
      9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在 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);
      }
    
    }
    
      9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    把两个 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 {}
    
      9
    • 10
    • 11
    • 12

    也可能存在其他组件使用相同的 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 {}
    
      9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    上面的例子用不同的值替换了 useClass 属性。 这样,我们可以在我们的应用程序中的任何地方使用 AuthService - 而无需进行进一步的更改。

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

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载