为什么在这个angular2示例中我仍然需要@inject?

时间:2016-06-30 13:34:42

标签: dependency-injection angular factory-pattern

这可能是一个特殊情况(注入浏览器本机窗口对象),但是当我的类已经有@Injectable()时,我仍然对为什么我仍然需要@Inject()参数装饰器感到困惑。装饰器。

采用这个简化的例子:

import { provide, bootstrap, Injectable, Inject } from '@angular/core';


@Injectable()
export class Token {
  private token: string;

  public constructor(token: string, window: Window) {
    this.token = window.atob(token);
  };

  public getToken(): string {
    return this.token;
  }
}


@Injectable()
export class TokenFactory {
  private window: Window;

  public constructor(window: Window) {
    this.window = window;
  }

  public createToken(token: string): Token {
    return new Token(token, this.window);
  }
}


@Component({
  template:   `
    <p *ngFor="let token of tokens">
      Encoded: {{token.getToken()}}
    </p>
  `,
  providers:  [ TokenFactory ]
})
class MainComponent {
  public tokens: Token[];

  public constructor(factory: TokenFactory) {
    this.tokens = [
      factory.create('token-1'),
      factory.create('token-2')
    ];
  };
}


bootstrap(
  MainComponent, [
    provide(Window, { useValue: window })
]);

概述:我们有一个令牌类,它代表一个可能在组件或其他服务中多次存在的对象(因此没有单例)。令牌类取决于全局窗口对象(例如,用于base64编码)。 为了使这个可测试,我们在引导期间为全局window object定义了应用程序范围的提供程序,而不是直接在令牌服务中使用它。

主要组件需要动态创建令牌,因此我们创建并注入一个简单的工厂服务 TokenFactory ,它还需要窗口提供程序(在构造期间将其传递给令牌类)。

问题:在浏览器中执行错误

时失败
Can't resolve all parameters for TokenFactory: (?).

但可以通过将@Inject(Window)装饰器添加到工厂构造函数 window 参数来修复。

现在,我有点困惑,因为大多数指南/教程解释说,在使用Injectable装饰器装饰类时,typescript中不需要注入装饰器,所以为什么示例在不使用@Inject的情况下失败()装饰者

配置: emitDecoratorMetadata experimentalDecorators 设置已启用,我正在使用 tsc 1.8.10 angular2 rc.3

PS: 我也开放进行一般设计改进。

(例如,在生产场景中,我可能只会导出令牌界面而不是整个类)

1 个答案:

答案 0 :(得分:5)

我不清楚这个问题到底是什么,但是

如果没有string

,注入的构造函数参数的

类型@Inject(...)没有任何意义

@Injectable()
export class Token {
  private token: string;

  public constructor(token: string, window: Window) { // <<== invalid
    this.token = window.atob(token);
  };

  public getToken(): string {
    return this.token;
  }
}

但是因为你正在使用它

new Token(token, this.window);

似乎应该从此课程中删除@Injectable()

关于错误消息:看起来Window未正确导入,或者类型不是OpaqueTokenstring

如果依赖注入应使用与参数类型不同的键,则需要

@Inject()。在您的情况下,Window看起来不是类型(类),因此在使用时不起作用。