5

今天我偶然發現了一些我認爲不會引起麻煩的事情。在Java和Spring中,我可以聲明兩個實現給定接口的bean,而在另一個注入它們的類中,我只能使用接口;這實際上就是我喜歡IoC的原因:你並不需要知道你正在使用什麼對象,只有它是kind角2可注射接口?

所以在我的小Angular2 /打字稿程序,我試圖做同樣的:

webapp.module.ts:

... 
import { WebAppConfigurationService } from './app/services/webapp.configuration.service'; 

@NgModule({ 
    ... 
    providers: [WebAppConfigurationService] 
}) 
export class AppModule { } 

tnsapp.module.ts:

... 
import { TnsConfigurationService } from './services/tns.configuration.service'; 

@NgModule({ 
    ... 
    providers: [TnsConfigurationService] 
}) 
export class AppModule { } 

這兩個模塊都使用不同的提供者:TnsConfigurationServiceWebAppConfigurationService

然而,這兩個@Injectable服務實現相同的接口:

configuration.interface:

export interface IConfigurationService { 
    ... 
} 

最後,在我的組成部分之一,我用這些模塊我發現一個提供注射你在開始:

import { IConfigurationService } from './configuration.interface'; 

export class HeroesService { 

    constructor(private configurationService: IConfigurationService) { } 
} 

我的期望是這最後一個組件注入了正確的服務,即使在第儀表只是明確界定界面。當然,我得到一個錯誤(「錯誤:無法解析所有參數給英雄服務」)

現在,我不期待一個簡單的解決方案,因爲它聽起來像一個架構缺乏。但也許有人可以指出我的另一種設計?

+0

查看DI文檔https://angular.io/docs/ts/latest/guide/dependency-injection.html#typescript-interfaces-aren-t-valid-tokens – yurzui

+0

@yurzui我喜歡它:「這不是Angular的錯。「 :-)好吧,也許還有一個美麗的方式來做到這一點...我稍後會閱讀這個'OpaqueToken' – Sebas

+0

OpaqueToken主要用於非類提供者(工廠和值)。 – estus

回答

6

爲了提供者被注入,它應該被註冊爲提供者。沒有IConfigurationService供應商。它不能是一個提供者,因爲編譯後的JS代碼中不存在接口。

對本應該被用作提供者的令牌接口通常的做法是爲抽象類:

abstract class ConfigurationService { ... } 

@Injectable() 
class WebAppConfigurationService extends ConfigurationService { ... } 

... 
providers: [{ provide: ConfigurationService, useClass: WebAppConfigurationService }] 
... 

這個配方通常由角2本身,例如使用abstract NgLocalization classconcrete NgLocaleLocalization implementation

+0

這看起來確實不錯,明天早上我會通知你(UTC) – Sebas

+0

https://cdn.meme.am/cache/instances/folder556/64985556.jpg – Sebas

+0

這對於角度4/5還是最新的?來自其他支持DI的語言,比如Java,我覺得使用抽象類作爲提供者是非常奇怪的。 –