依赖注入 - 18233135268/iOS-develop GitHub Wiki


Table of Contents

@Injectable 和嵌套服务依赖

@Injectable()

// 该装饰器让 Angular 有能力识别依赖
@Injectable()
export class UserContextService {
}

配置注入器

// 我们并不需要自己创建一个 Angular 注入器,Angular 在启动期间会自动为我们创建一个全应用级的注入器(在 main.ts 文件中)
platformBrowserDynamic().bootstrapModule(AppModule

在 NgModule 中注册 provider

@NgModule({
  imports: [
    BrowserModule
  ],
  declarations: [
    AppComponent,
    CarComponent,
    HeroesComponent,
    HeroListComponent,
    InjectorComponent,
    TestComponent,
    ProvidersComponent,
    Provider1Component,
    Provider3Component,
    Provider4Component,
    Provider5Component,
    Provider6aComponent,
    Provider6bComponent,
    Provider7Component,
    Provider8Component,
    Provider9Component,
    Provider10Component,
  ],
  providers: [
    UserService,
    { provide: APP_CONFIG, useValue: HERO_DI_CONFIG }
  ],
  bootstrap: [ AppComponent, ProvidersComponent ]
})
export class AppModule { }

在组件中注册 provider

import { Component }          from '@angular/core';

import { HeroService }        from './hero.service';

@Component({
  selector: 'my-heroes',
  providers: [HeroService],
  template: `
  <h2>Heroes</h2>
  <hero-list></hero-list>
  `
})
export class HeroesComponent { }

在 NgModule 还是应用组件中注册

  1. NgModule 中的 provider 是被注册到根注入器的,所以任何注册到 NgModule 上的 provider 都可以被整个应用访问
  2. 注册到应用组件上的职能在该组件及其子组件中可用

注入实例

// 这是一个 service
import { Injectable } from '@angular/core';
import { HEROES }     from './mock-heroes';
@Injectable()
export class HeroService {
  getHeroes() { return HEROES;  }
}
// provider 的注入是在本组件的父组件中注册的
import { Component }   from '@angular/core';
import { Hero }        from './hero';
import { HeroService } from './hero.service';
@Component({
  selector: 'hero-list',
  template: `
  <div *ngFor="let hero of heroes">
    {{hero.id}} - {{hero.name}}
  </div>
  `
})
export class HeroListComponent {
  heroes: Hero[];
  constructor(heroService: HeroService) {
    this.heroes = heroService.getHeroes();
  }
}

显性注入器的创建

  injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]);
  let car = injector.get(Car);

单例服务

  1. 在一个注入器的范围内,依赖都是单例的。
  2. Angular DI 是一个分层的依赖注入系统,这意味着被嵌套的注入器可以创建它们自己的 service 实例。

service 需要别的 service

// service 需要依赖别的 service
import { Injectable } from '@angular/core';
import { HEROES }     from './mock-heroes';
import { Logger }     from '../logger.service';
@Injectable()
export class HeroService {
  constructor(private logger: Logger) {  }
  getHeroes() {
    this.logger.log('Getting heroes ...');
    return HEROES;
  }
}

为何 @Injectable()?

  1. @Injectable() 标志着一个类可以被注入器实例化。通常来讲,在试图实例化一个没有被标识为 @Injectable() 的类是时候,注入器将会报告错误。
  2. 建议为每个服务类都添加 @Injectable(), 包括那些没有依赖的。

⚠️ **GitHub.com Fallback** ⚠️