淺析angular2依賴注入


依賴注入介紹

控制反轉(zhuǎn)(Inversion of Control,縮寫為IoC),是面向?qū)ο?/b>編程中的一種設(shè)計(jì)原則,可以用來(lái)減低計(jì)算機(jī)代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡(jiǎn)稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉(zhuǎn),對(duì)象在被創(chuàng)建的時(shí)候,由一個(gè)調(diào)控系統(tǒng)內(nèi)所有對(duì)象的外界實(shí)體將其所依賴的對(duì)象的引用傳遞給它。也可以說(shuō),依賴被注入到對(duì)象中。

簡(jiǎn)而言之,?沒事你不要來(lái)找我,有事我會(huì)去找你。

Angular依賴注入

首先介紹幾個(gè)簡(jiǎn)單的概念。

1.注入器(Inject):就像制造工廠,提供了一些列的接口用于創(chuàng)建依賴對(duì)象的實(shí)例

2.Provider:用于配置注入器,注入器通過它來(lái)創(chuàng)建被依賴對(duì)象的實(shí)例,Provider把標(biāo)識(shí)映射到工廠方法中,被依賴的對(duì)象就是通過該方法創(chuàng)建的。

3.依賴(Dependence):指定了被依賴對(duì)象的類型,注入器會(huì)根據(jù)此類型創(chuàng)建對(duì)應(yīng)的對(duì)象。

在組件中注入服務(wù)

Angular在底層做了大量的初始化工作,這大大簡(jiǎn)化了創(chuàng)建依賴注入的過程,在組件中使用依賴注入需要完成以下三個(gè)步驟

-通過import導(dǎo)入被依賴對(duì)象的服務(wù)

-在組建中配置注入器。在啟動(dòng)組件時(shí),Angular會(huì)讀取@Component裝飾器里的providers元數(shù)據(jù),它是一個(gè)數(shù)組,配置了該組件需要使用到的所有依賴,Angular的依賴注入框架就會(huì)根據(jù)這個(gè)列表去創(chuàng)建對(duì)應(yīng)對(duì)象的實(shí)例。

-在組件構(gòu)造函數(shù)中聲明所注入的依賴。注入器就會(huì)根據(jù)構(gòu)造函數(shù)上的聲明,在組件初始化時(shí)通過第二步中的providers元數(shù)據(jù)配置依賴,為構(gòu)造函數(shù)提供對(duì)應(yīng)的依賴服務(wù),最終完成注入過程。



在服務(wù)中注入服務(wù)

除了組件服務(wù)依賴,服務(wù)間的相互調(diào)用也很常見。

//logger.service.ts


//contact.service.ts

//在組件的providers元數(shù)據(jù)中注冊(cè)服務(wù)

providers:[LoggerService,ContactService]

在上述中,LoggerService和ContactService這兩個(gè)服務(wù)都用了@Injectable()裝飾器,實(shí)際上它并不是必須的,只有一個(gè)服務(wù)依賴其他服務(wù)時(shí),才需要用@Injectable()顯示裝飾。上述的LoggerService服務(wù)并沒有依賴其他服務(wù),它可以不用@Injectable()裝飾,而ContactService服務(wù)依賴了其他服務(wù),則需要@Injectable()裝飾。


Angular官方推薦無(wú)論是否有依賴其他服務(wù),都應(yīng)該使用@Injectable()來(lái)撞死服務(wù)。一方面,開發(fā)者在給某個(gè)組件注入其他服務(wù)時(shí),無(wú)需再確認(rèn)該服務(wù)是否添加了@Injectable();另一方面,這也是一種良好的團(tuán)隊(duì)協(xié)作方式,整個(gè)團(tuán)隊(duì)遵循相同的開發(fā)原則。

在模塊中注入服務(wù)

在根組件中注入這個(gè)服務(wù),所有子組件都能共享這個(gè)服務(wù)。

在模塊中注入服務(wù)和之前的注入場(chǎng)景稍有不同。Angular在啟動(dòng)程序時(shí)會(huì)啟動(dòng)一個(gè)根模塊,并加載它所依賴的其他模塊,此時(shí)會(huì)生成一個(gè)全局的根注入器,由該注入器創(chuàng)建的依賴注入對(duì)象在整個(gè)應(yīng)用程序級(jí)別可見,并共享一個(gè)實(shí)例。同時(shí)根模塊會(huì)指定一個(gè)根組件并啟動(dòng),由該根組件添加的依賴注入對(duì)象是組件樹級(jí)別可見,在根組件以及子組件中共享一個(gè)實(shí)例。


層級(jí)注入

Angular以組件為基礎(chǔ),項(xiàng)目開發(fā)中自然會(huì)有層級(jí)嵌套的情況,這種組織關(guān)系組成了組件樹。根組件下面的各層級(jí)的子組件,可以出現(xiàn)在任何層級(jí)的任何組件中,每個(gè)組件可以擁有一個(gè)或多個(gè)依賴對(duì)象的注入,每個(gè)依賴對(duì)象對(duì)于注入器而言都是單例。


//生成唯一標(biāo)識(shí)服務(wù)


//子組件A


//子組件B


//父組件


結(jié)果將輸出:

Contact-List

ContactA:0.4500488165839276

ContactB:0.5389674473022938


每個(gè)子組件都創(chuàng)建了自己獨(dú)立的注入器,也就是說(shuō)通過依賴注入的Random服務(wù)都是獨(dú)立的,如果把注入器提升到父組件中,則結(jié)果將會(huì)不一樣。



此時(shí),結(jié)果變?yōu)?/p>

Contact-List

ContactA:0.6257492668005642

ContactB:0.6257492668005642

上述的輸出結(jié)果說(shuō)明了子組件繼承了父組件的注入器,所以子組件使用了相同的Random實(shí)例,輸出了相同的結(jié)果。

那么,該如何選擇在根組件還是在子組件中注入服務(wù)呢?

這取決于想讓注入的依賴服務(wù)具有局部性還是全局性,由于每個(gè)注入器總是將它提供的服務(wù)維持單例,因此,如果不需要針對(duì)每個(gè)組件都提供獨(dú)立的服務(wù)單例,就可以在根組件中注入,整個(gè)組件樹共享根注入器提供的服務(wù)實(shí)例;如果需要針對(duì)每個(gè)組件提供不同的服務(wù)實(shí)例,就應(yīng)該在格子組件中配置providers元數(shù)據(jù)來(lái)注入服務(wù)。

Angular如何查找到合適的服務(wù)實(shí)例呢?

在組件的構(gòu)造函數(shù)視圖注入某個(gè)服務(wù)的時(shí)候,Angular會(huì)先從當(dāng)前組件的注入器中查找,找不到就繼續(xù)往父組件的注入器查找,直到根組件注入器,最后到應(yīng)用根注入器,此時(shí)找不到的話就會(huì)報(bào)錯(cuò)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 版本:Angular 5.0.0-alpha 依賴注入是重要的應(yīng)用設(shè)計(jì)模式。它使用得非常廣泛,以至于幾乎每個(gè)人都稱...
    soojade閱讀 3,064評(píng)論 0 3
  • 依賴注入(DI -- Dependency Injection)是一種重要的應(yīng)用設(shè)計(jì)模式。Angular里面...
    tuacy閱讀 13,421評(píng)論 4 16
  • 一、什么是依賴注入 控制反轉(zhuǎn)(IoC) 控制反轉(zhuǎn)的概念最早在2004年由Martin Fowler提出,是針對(duì)面向...
    Keriy閱讀 3,575評(píng)論 0 8
  • 一、什么是依賴注入 控制反轉(zhuǎn) Inversion of Control (簡(jiǎn)稱IOC) 最早在2004年由Mart...
    笨蛋小明閱讀 3,224評(píng)論 3 6
  • 早上陪姐姐去醫(yī)院做最后一次產(chǎn)檢,公交車上人多到站的地方都少。一上車還是像往常一樣、沒人會(huì)讓座。一開始遇到那些明明看...
    漠熙閱讀 227評(píng)論 0 1

友情鏈接更多精彩內(nèi)容