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

Dependency injection 为什么在这个angular2示例中仍然需要@inject?,dependency-injection,angular,factory-pattern,Dependency Injection,Angular,Factory Pattern,这可能是一种特殊情况(注入浏览器本机窗口对象),但我还是有点困惑,为什么我的类已经有了@Injectable()decorator,而我仍然需要@injection()参数decorator 以这个简化的例子为例: 从'@angular/core'导入{provide,bootstrap,Injectable,injection}; @可注射() 导出类令牌{ 私有令牌:字符串; 公共构造函数(标记:字符串,窗口:窗口){ this.token=window.atob(token); }; pu

这可能是一种特殊情况(注入浏览器本机窗口对象),但我还是有点困惑,为什么我的类已经有了@Injectable()decorator,而我仍然需要@injection()参数decorator

以这个简化的例子为例:

从'@angular/core'导入{provide,bootstrap,Injectable,injection};
@可注射()
导出类令牌{
私有令牌:字符串;
公共构造函数(标记:字符串,窗口:窗口){
this.token=window.atob(token);
};
public getToken():字符串{
返回此.token;
}
}
@可注射()
出口级代币厂{
私人窗口:窗口;
公共构造函数(窗口:窗口){
this.window=窗口;
}
公共createToken(令牌:字符串):令牌{
返回新令牌(令牌,此.window);
}
}
@组成部分({
模板:`

编码:{{token.getToken()}}

`, 提供者:[令牌工厂] }) 类主组件{ 公共代币:代币[]; 公共构造函数(工厂:令牌工厂){ 此参数为。令牌=[ factory.create('token-1'), 创建('token-2') ]; }; } 引导( 主要组成部分[ 提供(窗口,{useValue:Window}) ]);
概述:我们有一个令牌类,它表示一个对象,该对象可以在一个组件或另一个服务中多次存在(因此没有单例)。令牌类取决于全局窗口对象(例如,对于base64编码)。 为了使这一点可测试,我们在引导期间为全局服务定义了一个应用程序范围的提供者,而不是在令牌服务中直接使用它

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

问题:在浏览器中执行此操作时失败,并出现错误

Can't resolve all parameters for TokenFactory: (?).
但可以通过向Factorys构造函数窗口参数添加@Inject(Window)装饰器来修复

现在,我有点困惑了,因为大多数指南/教程解释说,在用可注入装饰器装饰类时,typescript中不需要注入装饰器,那么为什么这个示例没有使用@inject()装饰器就失败了呢

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


PS:我也对总体设计改进持开放态度


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

我不清楚问题的实质是什么,但是

如果没有
@Inject(…)

似乎应该从这个类中删除
@Injectable()


关于错误消息:看起来
窗口
未正确导入,或者它不是类型,而是
OpaqueToken
字符串


如果依赖项注入应使用与参数类型不同的键,则需要使用
@Inject()
。在您的情况下,它看起来像是
Window
不是一个类型(类),因此在这样使用时不起作用。

您能详细介绍一下Window类的定义位置和导入方式吗?谢谢它是作为窗口公开的全局浏览器(lover case)。它在引导过程中被注入底部。嗯…,在这种情况下,提供者名称是否必须是字符串或更好的OpaqueToken,因为typescript/angular可能会混淆窗口名称属性?我忘了提到,这是一个运行时(浏览器)错误,而不是编译时(tsc)…很好,你是对的,我应该删除Token类的可注入项,因为令牌参数不打算被注入,实际上更多的是一个输入参数。您关于窗口的评论让人耳目一新,因为窗口对象来自浏览器,它可能没有经过修饰(没有元数据),因此需要在Factorys窗口参数上使用InjectDocorator;听起来不错。
@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);