2016-06-07 82 views
5

我工作的一個角項目在被設計成非常模塊化分鐘 - sections of the app can be enabled and disabled for different clients using Webpack.這種結構是很好的工作對我來說,到目前爲止,但一個問題,我已經運行到正在研究如何處理可能並不總是存在的服務。訪問的角度服務,可能會或可能不存在

我目前的解決方案是非常簡單 - 我用$injector.has()檢查服務目前存在的,如果是這樣,我用$injector.get()抓住它:

function initialize($injector) { 
    if ($injector.has("barcode")) { 
     let barcode = $injector.get("barcode"); 

     // Do stuff with the barcode service 
    } 
} 

這似乎是工作 - 不過,我可以」 t找到關於使用這種模式的很多信息,以及它是否有任何潛在的缺點。

所以,我的問題是:

  • 是否有什麼注意事項使用注射器這樣,我應該知道的?
  • 是否有這樣做的更好/更地道的方式?

回答

2

這可能是完成你想要什麼是最好的辦法;然而,在這樣做,請注意,您是從Dependency Injection(DI)移動到Service Locator模式。

以下from the Angular 2 docs是很相關的(重點煤礦):

我們避免這種技術除非我們真正需要它。它鼓勵我們在這裏看到一個粗心的抓包方法。很難解釋,理解和測試。我們無法通過檢查構造函數知道這個類需要什麼或者它會做什麼。它可以從任何祖先組件獲得服務,而不僅僅是它自己的服務。我們被迫拼寫實施以發現它的功能。

框架開發人員可能會採取這種方法時,他們必須一般和動態獲取服務

(旁白:這是值得擁有過什麼是未來的dependency injection in Angular 2讀 - 可選的依賴,工廠提供商等)

角1的docs on the matter提及它相抵觸的The Law of Demeter(它是運行當然更多的是指導而不是法律,對吧?)。

在任何情況下,只是一些額外的事情需要注意的:

  • 你不會被警告(通過具有errors thrown),其中這是用來循環依賴的;事實上,這通常是人們用來解決這些警告的技術。

  • 由於您現在對注入器有依賴性,除了注入它之外,您的單元測試將需要模擬$注入器或使用類似module('moduleThatIsUsingInjectorExplicitly', function($provide) { $provide.value('barcode', barCodeMock);}之類的東西。

  • 正如上面的引用中所提到的那樣,您的代碼將不太清晰,因爲這些'可選'依賴關係在通常的地方沒有定義。

很多其他的讀取服務定位器模式,並與DI形成鮮明對比。有趣的是,對我們來說,實際的影響可能是有限的,特別是因爲JavaScript缺乏界面/抽象和Angular 1的DI實現意味着真正的差異點較少。

+0

明智的答案,非常感謝! Angular 2的可選依賴關係更多的是我所追求的 - 這更像是一個權宜之計解決方案,直到我們可以遷移到目前爲止(目前正在等待第三方UI框架進行更新,有望在本世紀的某個時候發生......) –

+0

取決於根據您的需求,可能還有值得嘗試創建可用於可選項目的「存根」服務,從而允許您仍然擁有DI。我必須重新檢查,但是我相信Angular會允許您在先前提供的服務中加載一個新的同名服務。和/或你可以使用裝飾器(https://docs.angularjs.org/guide/decorators)替換或裝飾這些「存根」。也許值得重視複雜性。我沒有測試過這個... – JcT

+0

是的,這聽起來像是值得研究的東西 - 只是增加的複雜性是否值得。我是我公司當時唯一的JavaScript人員,我將不得不教導其他人,所以我傾向於保持簡單:p –

相關問題