Angular 4 DI通过接口

时间:2017-08-16 20:45:19

标签: angular dependency-injection code-injection

我遵循了文档如何通过接口使用InjectionToken进行注入。我刚刚创建了一个小项目 -

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 Tools中遇到的错误

  

compiler.es5.js:1690未捕获错误:无法解析AppComponent的所有参数:(?)。       在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(< / p>

这是plunkr - https://embed.plnkr.co/qQP5BhNzgu2F4FYclG1e/

1 个答案:

答案 0 :(得分: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');

对于真正的应用程序而言,这通常不会成为问题,因为使用它们的提供程序和位置位于不同的模块文件中。