Angular2依賴注入

曾自己借助阿里云和hexo搭了個站點(diǎn),現(xiàn)已廢棄,過往寫的博客暫挪到此處漓雅。


title: Angular2依賴注入
subtitle: 小白學(xué)Angular2
date: 2016-11-24 22:53:51
tags:
- 技術(shù)
- Angular2
- 學(xué)習(xí)筆記


依賴注入用我這個小白的話說衣迷,就是定義一個類的時候,將某些依賴作為類的參數(shù)邮破,即:

var myClass = function( arg1,arg2){
    this.arg1 = arg1;
    this.arg2 = arg2;
}

初始化該類的時候诈豌,就可以將這些依賴當(dāng)做參數(shù)傳遞進(jìn)去仆救。
這樣,當(dāng)arg1和arg2改變的時候矫渔,我們可以不用動這個myClass內(nèi)部的代碼彤蔽。

這個用法在純js時代就常用,只是現(xiàn)在叫做依賴注入庙洼。目的是為了顿痪,解耦。

angular 依賴注入與 我的myClass的不同在于
如果arg1和arg2都是類的實(shí)例送膳,
myClass需要先實(shí)例化這些類员魏,然后再調(diào)用new myClass(instance1,instance2)。

而Angular叠聋,不需要先實(shí)例化每一個依賴注入的類撕阎。Angular自己會幫你實(shí)例化。但是需要以下幾步
構(gòu)造函數(shù)參數(shù)中有這些類: constructor(heroService:HeroService)
這個constructor的類有一個@Component裝飾器(這個一般都不必說碌补。虏束。)
@Component中有這些類的providers信息,即providers:[HeroService]
對于被依賴的那些類厦章,需要在export class之前加上@Injectable()镇匀,否則注入器會報(bào)錯
注:服務(wù)是可以繼承的

Angular中的顯性注入器

首先這應(yīng)當(dāng)是沒有必要的,只要正確使用依賴注入袜啃,angular自己會管理好注入器的創(chuàng)建和調(diào)用汗侵。
當(dāng)方式如下:

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

直接使用注入器Injector的方式

可以直接使用注入器工作,但不方便閱讀群发,難以理解晰韵,所以盡量避免:
在@Component中添加這些類的providers信息,即providers:[HeroService]
在constructor中注入Injector(Injector本身就是一個可注入的服務(wù))
然后在Component中通過injector.get方式獲得providers提供的服務(wù)(即類HeroService)
如果get失敗會拋出異常熟妓,get方法可以帶第二個參數(shù)雪猪,表示如果服務(wù)沒找到就當(dāng)做默認(rèn)值返回。

注入器的提供商們:

令牌token:它作為鍵值key使用起愈,用于定位依賴值只恨,以及注冊這個提供商
providers: [Logger]
provider definition object:知道如何創(chuàng)建依賴值得配方,有很多方式創(chuàng)建依賴值

[{ provide: Logger, useClass: Logger }]
1. 備選的類提供商
[{ provide: Logger, useClass: BetterLogger }]

當(dāng)請求Logger時抬虽,提供BetterLogger
(不同于別名官觅,見3)

2. 帶依賴的類提供商
[ UserService,
  { provide: Logger, useClass: EvenBetterLogger }]

因?yàn)镋venBetterLogger注入了UserService(?阐污?可是為什么不會在EvenBetterLogger中自動調(diào)用休涤??還要在調(diào)用EvenBetterLogger的地方在provide聲明一下這個服務(wù)疤剑。)

3. 別名類提供商
[ NewLogger,
  // Alias OldLogger w/ reference to NewLogger
  { provide: OldLogger, useExisting: NewLogger}]

對比1滑绒,1會創(chuàng)建兩個實(shí)例闷堡,(?疑故?1在什么時候回用到杠览??需要創(chuàng)建兩個實(shí)例)

[ NewLogger,
  // Not aliased! Creates two instances of `NewLogger`
  { provide: OldLogger, useClass: NewLogger}]
4. 值提供商
[{ provide: Logger, useValue: silentLogger }]

silentLogger是一個對象

5. 工廠提供商

在需要動態(tài)創(chuàng)建依賴值得情況下纵势,使用此方式

//deps為該服務(wù)需要的依賴踱阿,通過注入器傳入工廠方法
export let heroServiceProvider =
  { provide: HeroService,
    useFactory: heroServiceFactory,
    deps: [Logger, UserService]
  };
let heroServiceFactory = (logger: Logger, userService: UserService) => {
  return new HeroService(logger, userService.user.isAuthorized);
};
//滿足的場景
constructor(
  private logger: Logger,
  private isAuthorized: boolean) { }

getHeroes() {
  let auth = this.isAuthorized ? 'authorized ' : 'unauthorized';
  this.logger.log(`Getting heroes for ${auth} user.`);
  return HEROES.filter(hero => this.isAuthorized || !hero.isSecret);
}

注:我們?yōu)榱酥貜?fù)利用導(dǎo)出一個變量捕獲了這個工廠提供商:heroServiceProvider。但也可以不用導(dǎo)出再使用钦铁,直接在需要該服務(wù)的地方的provider里加上即可软舌,同1、2牛曹、3佛点、4
依賴注入令牌
注入器維護(hù)一個內(nèi)部的令牌-提供商映射表。
對于類而言黎比,類名就是這個令牌超营。
非類依賴

export interface AppConfig {
  apiEndpoint: string;
  title: string;
}

export const HERO_DI_CONFIG: AppConfig = {
  apiEndpoint: 'api.heroes.com',
  title: 'Dependency Injection'
};

TypeScript接口不是一個有效的令牌。
Angular不支持阅虫。
解釋為:在強(qiáng)類型語言中接口是首選的用于查找依賴的主鍵演闭,再使用依賴注入很奇怪。
TS在生成JS之后颓帝,不會再有接口米碰。
Opaque Token
解決方案是使用一個Opaque Token(不透明的令牌)

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

export let APP_CONFIG = new OpaqueToken('app.config');

使用OpaqueToken對象注冊依賴的提供商

providers: [{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }]

在@Inject的幫助,將這個配置對象注入到需要的構(gòu)造函數(shù)中

constructor(@Inject(APP_CONFIG) config: AppConfig) {
  this.title = config.title;
}

可選依賴

import { Optional } from '@angular/core’;

constructor(@Optional() private logger: Logger) {
  if (this.logger) {
    this.logger.log(some_message);
  }
}

注:當(dāng)使用@Optional()的時候购城,需要為空值做準(zhǔn)備

進(jìn)階:

多級依賴注入器
angular的多級依賴注入系統(tǒng)支持與組件樹并行的嵌套式注入器
大白話吕座,子組件通過冒泡的方式向上查找需要的服務(wù);
其次工猜,每個注入器都會把它提供的服務(wù)處理成單例米诉,但當(dāng)我們并不想共享菱蔬,想為單個組件生成一個實(shí)例篷帅,則不要把服務(wù)注入到父級的以及父級的父級的組件中。

其他規(guī)范:

建議為每個服務(wù)類都添加@Injectable()拴泌,無論是否被依賴魏身,出于為了以后可能被依賴著想以及一致性

@Component和@Directive @Pipe都是InjectableMetadata的子類型,所以沒有必要為component添加@Injectable方法

注入器可以從編譯后的Javascript代碼中讀取類的元數(shù)據(jù)蚪腐,并使用構(gòu)造函數(shù)的參數(shù)類型信息來決定注入什么箭昵。
(不是每個JavaScript類都有元數(shù)據(jù)。TS編輯器默認(rèn)忽視元數(shù)據(jù)回季。如果tsconfig.json中的emitDecoratorMetadata編譯器選項(xiàng)為true家制,編譯器就會在生成的Javascript中為每個至少擁有一個裝飾器的類添加元數(shù)據(jù)正林。
注入器使用一個類的構(gòu)造元數(shù)據(jù)來決定依賴類型(?颤殴?依賴類型有些什么觅廓??)涵但,該構(gòu)造元數(shù)據(jù)就是構(gòu)造函數(shù)的參數(shù)類型所標(biāo)識的杈绸。TS為任何帶有一個裝飾器的類生成這樣的元數(shù)據(jù),任何裝飾器都生成矮瘟。當(dāng)然瞳脓,使用一個合適的Injectable裝飾器來標(biāo)識更有意義。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末澈侠,一起剝皮案震驚了整個濱河市劫侧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哨啃,老刑警劉巖板辽,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異棘催,居然都是意外死亡劲弦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門醇坝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邑跪,“玉大人,你說我怎么就攤上這事呼猪』” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵宋距,是天一觀的道長轴踱。 經(jīng)常有香客問我,道長谚赎,這世上最難降的妖魔是什么淫僻? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮壶唤,結(jié)果婚禮上雳灵,老公的妹妹穿的比我還像新娘。我一直安慰自己闸盔,他們只是感情好悯辙,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般躲撰。 火紅的嫁衣襯著肌膚如雪针贬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天拢蛋,我揣著相機(jī)與錄音坚踩,去河邊找鬼。 笑死瓤狐,一個胖子當(dāng)著我的面吹牛瞬铸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播础锐,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼嗓节,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了皆警?” 一聲冷哼從身側(cè)響起拦宣,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎信姓,沒想到半個月后鸵隧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡意推,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年豆瘫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菊值。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡外驱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腻窒,到底是詐尸還是另有隱情昵宇,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布儿子,位于F島的核電站瓦哎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏柔逼。R本人自食惡果不足惜蒋譬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望卒落。 院中可真熱鬧羡铲,春花似錦蜂桶、人聲如沸儡毕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腰湾。三九已至雷恃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間费坊,已是汗流浹背倒槐。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留附井,地道東北人讨越。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像永毅,于是被迫代替她去往敵國和親把跨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 很多朋友羨慕我的2016沼死,因?yàn)閷?shí)現(xiàn)了很多的突破着逐,但是于我簡直就是把自己扔進(jìn)了紛亂的世界。自己原本沉穩(wěn)的生活被很多壓...
    華松科技閱讀 162評論 0 1
  • 今天上午意蛀,我和田云鵬約好踢足球耸别,由我先發(fā)球,我把球放在地上县钥,后退好幾步秀姐,猛然一踢,球進(jìn)了若贮!還差點(diǎn)砸到了他的...
    面朝大海春暖花開_ba97閱讀 59評論 0 0
  • 愛情好像是年輕人的專利兜看,甜蜜而美好锥咸!婚后的愛情,定義在了忠誠與堅(jiān)守细移。 像那些婚后出軌的明星搏予,比如王寶強(qiáng)的老婆,比如...
    A熊清芳閱讀 533評論 9 4
  • 今天他讀書很棒弧轧,每天讀書都會生氣因?yàn)樗粣圩x書雪侥。今天在讀書的時候自己讀笑了。讀懂了書里的故事精绎,他說很有意思速缨。我很高...
    我想要的你不懂閱讀 109評論 0 0