Tom*_*asi 2 dependency-injection factory-pattern angular
这可能是一个特殊情况(注入浏览器本机窗口对象),但是当我的类已经有一个@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 })
]);
Run Code Online (Sandbox Code Playgroud)
概述:我们有一个令牌类,它表示在组件或其他服务中可以多次存在的对象(因此没有单例).令牌类取决于全局窗口对象(例如,用于base64编码).为了使这个可测试,我们在引导期间为全局窗口对象定义应用程序范围的提供程序,而不是直接在令牌服务中使用它.
主要组件需要动态创建令牌,因此我们创建并注入一个简单的工厂服务TokenFactory,它还需要窗口提供程序(在构造期间将令牌类传递给它).
问题:在浏览器中执行错误时失败
Can't resolve all parameters for TokenFactory: (?).
Run Code Online (Sandbox Code Playgroud)
但可以通过向工厂构造函数窗口参数添加@Inject(Window)装饰器来修复.
现在,我有点困惑,因为大多数指南/教程解释了在使用Injectable装饰器装饰类时,typescript中不需要inject装饰器,那么为什么示例会在不使用@Inject()装饰器的情况下失败?
配置: emitDecoratorMetadata和experimentalDecorators设置已启用,我正在使用tsc 1.8.10和angular2 rc.3.
PS: 我也对一般的设计改进持开放态度.
(例如.在生产场景中,我可能只导出令牌接口而不是整个类)
我不清楚问题究竟是什么,但是
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;
}
}
Run Code Online (Sandbox Code Playgroud)
但是因为你正在使用它
new Token(token, this.window);
Run Code Online (Sandbox Code Playgroud)
似乎@Injectable()应该从这个班级中删除.
关于错误消息:它看起来Window没有正确导入或它不是一个类型而是一个OpaqueToken或一个string.
@Inject()如果依赖注入应使用与参数类型不同的键,则是必需的.在你的情况下,它看起来Window不是一个类型(类),因此在使用时不起作用.
| 归档时间: |
|
| 查看次数: |
364 次 |
| 最近记录: |