Angular 2.0 DI我可以依赖于抽象吗?

时间:2016-03-20 15:25:41

标签: angular typescript angular2-di

我一直在阅读关于依赖倒置的Angular 2.0 docs,我也在寻找一些online examples

我的理解是@injectable装饰器使用带有emitDecoratorMetadata标志的TypeScript编译器来创建用于解析依赖关系的元数据。以下面的课程为例:

enter image description here

TypeScript编译器使用emitDecoratorMetadata通过元数据声明DataService类具有类型为Http的构造函数参数。

一旦我们使用@Injectable声明了类的依赖关系,我们可以指出需要使用Provides@App中的@Component选项将其注入到某些组件中装饰者。

enter image description here

我了解emitDecoratorMetadata的行为,我知道它无法为接口发出元数据。因此,我认为我不能依赖IHttp而不是Http

enter image description here

我的假设是否正确?我可以依赖“Depend upon Abstractions. Do not depend upon concretions.”还是那些目前无法做到的事情?我认为只要emitDecoratorMetadata能够序列化接口,就会解决这个问题。

2 个答案:

答案 0 :(得分:3)

目前,您需要提供类型,字符串名称或OpaqueToken作为提供商的密钥 不支持接口,因为该信息在运行时不可用。如果这个被添加,我肯定DI会支持它们(它已经在Dart中得到支持)。

答案 1 :(得分:1)

如果您使用的是TypeScript,我会为您提供解决方案。

我没有使用Angular 2.0,但我们开发了类似的DI库(intakejs)。问题是TS编译器只为类而不是接口发出反射元数据(它们被视为" object")。

希望他们能够进一步添加此类功能,但现在我们正在使用基于TypeScript的declaration merging功能的hack。我们的想法是你可以声明接口,并将其与字符串或其他一些运行时ID合并:

export interface IMyInjectable {
    foo(): string;
}
export const IMyInjectable = 'MyInjectable';

假设您已实现该界面:

@Injectable('MyInjectable')
class MyInjectable implements IMyInjectable {
    foo(): string { return 'hello' }
}

然后,您可以依赖消费者类中的抽象:

class MyConsumer {

    @Inject(IMyInjectable)
    private myInjectable: IMyInjectable;

}

我希望这个小技巧可以解决你的问题。