2017-08-16 75 views
0

我遵循文檔如何使用InjectionToken通過接口注入。我剛剛創建了一個小項目 -角度4 DI通過接口

export interface MyInterface { 
    sayHello(); 
} 

@Injectable() 
export class MyService implements MyInterface { 
    sayHello() 
    { 
    throw new Error("Method not implemented."); 
    } 
} 

app.module

export let MY_SERVICE = new InjectionToken<MyInterface>('MY_SERVICE'); 
    providers: [ 
    { 
     provide: MY_SERVICE, 
     useClass : MyService 
    } 
],` 

這裏是app.component.ts

@Component({ 
selector: 'app-root', 
templateUrl: './app.component.html', 
styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
title = 'app'; 
constructor(@Inject(MY_SERVICE) private myService : MyInterface) { 
    } 
} 

這是一個錯誤我在Chrome工具得到

compiler.es5.js:1690 Uncaught Error: Can't resolve all parameters for AppComponent: (?). at syntaxError (compiler.es5.js:1690) at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver._getDependenciesMetadata (compiler.es5.js:15765) at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver._getTypeMetadata (

這裏是plunkr - https://embed.plnkr.co/qQP5BhNzgu2F4FYclG1e/

+0

我會期待它的工作。如果MY_SERVICE未在模塊提供程序中註冊,則會發生該錯誤。上面的代碼被截斷,並不確定它是什麼。無論如何,當抽象類同時用作接口和令牌時,它會更好。 – estus

+0

可能重複的[導出類作爲Angular2中的接口](https://stackoverflow.com/questions/43572149/export-class-as-interface-in-angular2) – estus

+0

@estus我不認爲它是重複的,因爲我想使用確切的接口,而不是抽象類。你的意思是什麼> MY_SERVICE沒有在模塊提供商註冊?我認爲我已經做到了 –

回答

1

original code的問題是,MY_SERVICE注射標記實際上是用於注射後定義的。

爲了避免這種情況,應該在這之前被定義爲:

export let MY_SERVICE = new InjectionToken<MyInterface>('MY_SERVICE'); 
... 
constructor(@Inject(MY_SERVICE) private myService: MyInterface) { 
... 

另外,可以使用forwardRef幫手,它的目的是避免競爭條件類似的:

... 
constructor(@Inject(forwardRef(() => MY_SERVICE)) private myService: MyInterface) { 
... 
export let MY_SERVICE = new InjectionToken<MyInterface>('MY_SERVICE'); 

這通常榮獲」對於真實應用程序而言,它們的提供者和地點位於不同的模塊文件中。