依賴注入能幫助我們管理對象,種種好處這里就不說了,主要記錄下angular2中的依賴注入。部分代碼直接來自angular中文官網。
基本依賴注入
@Injectable()
export class Logger {
logs: string[] = [];
log(message: string) {
this.logs.push(message);
console.log(message);
}
}
使用@Injectable()修飾符,這樣ng依賴注入器便能根據需要注入該類。
要使用該類,還需要對該服務進行注冊
providers: [ Logger ],可以在模塊中的提供商中聲明,也可以在需要使用該服務的組件中聲明。
聲明后就能直接使用該服務了,ng注入器會為我們實例化該類:
constructor(private logger:Logger){}
大多數(shù)情況下可以這樣寫,當然也能直接從注冊器中獲取對象this.logger = this.injector.get(Logger);
服務提供商provider
providers: [ Logger ]是注冊服務提供商[{ provide: Logger, useClass: Logger }]的一種簡寫方式。
provide是令牌 (token),它作為鍵值 (key) 使用,它需要是一個typescript類,而不能是接口,因為js中不支持接口
useClass是實際的類型,因此我們也可以使用其他類型,BetterLogger,只要其與Logger有相同的接口
export class BetterLogger{
logs: string[] = [];
log(msg: string){
console.log("better logger");
}
}
可以使用
providers: [BetterLogger, {provide:Logger, useExisting:BetterLogger} ]的方式來實現(xiàn)別名提供商,在接口改進或提升中有作用。
[{ provide: Logger, useValue: silentLogger }]為值提供商,silentLogger 為一個對象,該對象與Logger有相同的屬性及行為聲明。
工廠提供商
以上注入器為實例化對象都不涉及參數(shù),當需要指定的參數(shù)來實例化對象是則可以使用工廠提供商。
export class FactoryLogger{
constructor(private isAuthorized:boolean){}
logs: string[] = [];
log(msg: string){
console.log("factory logger");
if(this.isAuthorized){
console.log('authorized');
}
}
}
export let LoggerFactory=(authorized:Authorized) => {return new FactoryLogger(authorized.isAuthorized())};
@Injectable()
export class Authorized{
isAuthorized(){
return true;
}
}
在providers注冊方式為providers: [Authorized,{provide: Logger, useFactory:LoggerFactory, deps:[Authorized]} ]
FactoryLogger服務需要一個bool值來實例化,我們提供了一個工廠方法LoggerFactory,該方法接收一個Authorized服務對象,并從該對象中獲取bool值。
useFactory為使用的工廠方法,deps我需要的其他服務。
非類提供商
有是我們的依賴僅僅為一個對象,而不是類的情況下,我們可以使用非類提供商,假設有以下配置對象:
export interface AppConfig {
apiEndpoint: string;
title: string;
}
export const HERO_DI_CONFIG: AppConfig = {
apiEndpoint: 'api.heroes.com',
title: 'Dependency Injection'
};
接口不能作為提供商的key,因此[{ provide: AppConfig, useValue: HERO_DI_CONFIG })]配置的方式是行不通的。
可以通過OpaqueToken類來使用字符串作為注冊服務提供商的鍵:
import { OpaqueToken } from '@angular/core';
export let APP_CONFIG = new OpaqueToken('app.config');
使用方式如下
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }]
})
export class AppComponent{
title = 'app works!';
constructor(@Inject(APP_CONFIG) config: AppConfig) {
this.title = config.url;
}
}
一些相關修飾符
1.@Optional()當沒有注冊提供商時,會設置注入的對象為null而不報錯,用在要注冊的對象前。
2.@Inject(APP_CONFIG) 參數(shù)修飾符聲明一個依賴。