依赖注入的层级等等请查看示意图
https://www.processon.com/view/618b434c1e0853689b033111?fromnew=1
依赖提供商
不同的类都可用于提供相同的服务。 比如,下面的代码告诉注入器,当组件使用 Logger 令牌请求日志对象时,给它返回一个 BetterLogger 实例。
1 2
| [{ provide: Logger, useClass: BetterLogger }]
|
当用BetterLogger替代Logger后,此时BetterLogger在应用内会被实例化两次
1 2 3 4 5
| [ BetterLogger, { provide: Logger, useClass: BetterLogger } ]
|
所以如果当你需要必须实例化一次BetterLogger的时候就用到了useExisting
1 2 3 4 5
| [ BetterLogger, { provide: Logger, useExisting: BetterLogger } ]
|
值提供商
有时候你会希望注入字符串、函数或对象。通常会用来定义参数或者API请求地址等
1 2 3 4 5 6
| export const HERO_DI_CONFIG: AppConfig = { apiEndpoint: 'api.heroes.com', title: 'Dependency Injection' };
[{ provide: AppConfig, useValue: HERO_DI_CONFIG })]
|
这里需要注意的是,我们的令牌除了本身可以使用的值意外也可以使用字符串或者InjectionToken对象
1 2 3 4 5 6 7 8 9
| export const HERO_DI_CONFIG: AppConfig = { apiEndpoint: 'api.heroes.com', title: 'Dependency Injection' };
[{ provide: 'APP_CONFIG', useValue: HERO_DI_CONFIG })]
constructor(@Inject('APP_CONFIG') GLOBAL_ENV){}
|
1 2 3 4 5 6 7
| import { InjectionToken } from '@angular/core';
export const APP_CONFIG = new InjectionToken<AppConfig>('app.config');
//config.ts
|
1 2 3 4 5 6 7 8 9
| export const HERO_DI_CONFIG: AppConfig = { apiEndpoint: 'api.heroes.com', title: 'Dependency Injection' };
[{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG })]
constructor(@Inject(APP_CONFIG) GLOBAL_ENV){}
|
相比于官方提供的方法这里更简洁的方法可以使用字符串,这样不需要在使用是频繁的引入config.ts文件
工厂提供商
当需要动态创建依赖值时,比如需要从第三方库创建依赖时,你不能直接访问第三方库的实例,这时候就需要工厂提供商,比如当我们登录后可以拿到某个列表,不登录时会返回一个空列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| export class HeroService {
HEROES = [1, 2, 3, 4]
constructor( private isAuthorized: boolean ) { }
getHeroes() { let HEROES = [];
if (this.isAuthorized) { HEROES = this.HEROES } else { HEROES = []; }
return HEROES; } }
|
这时你需要一个isAuthorized标志来控制,虽然HeroService不能直接访问UserService,但是工厂函数可以
1 2 3 4 5 6 7 8 9 10
| let heroServiceFactory = (userService: UserService) => { return new HeroService(userService.user.isAuthorized); };
export let heroServiceProvider = { provide: HeroService, useFactory: heroServiceFactory, deps: [UserService] };
|
组件中使用时
1
| heroServiceProvider.useFactory(this.UserService).getHeroes()
|