Angular 2.0 DI 我可以依赖抽象吗?
Angular 2.0 DI can I depend upon abstractions?
我一直在阅读 Angular 2.0 docs about dependency inversion and I've been looking also at some online examples。
我的理解是 @injectable
装饰器使用带有 emitDecoratorMetadata
标志的 TypeScript 编译器来创建用于解析依赖项的元数据。以下面的例子 class:
TypeScript 编译器使用 emitDecoratorMetadata
通过元数据声明 DataService
class 具有类型为 Http
.
的构造函数参数
一旦我们使用 @Injectable
声明了 class 的依赖项,我们就可以使用 [=18= 中的 Provides
选项指示它需要被注入到某些组件中] 或 @Component
个装饰器。
我知道 emitDecoratorMetadata
的行为并且我知道它不能为接口发出元数据。因此,我假设我不能依赖 IHttp
而不是 Http
:
我的假设正确吗?我可以依赖 “Depend upon Abstractions. Do not depend upon concretions.” 还是目前不可能的事情?我认为一旦 emitDecoratorMetadata
能够序列化接口,这个问题就会得到解决。
目前您需要一个类型、一个字符串名称或一个 OpaqueToken
作为提供商的键。
不支持接口,因为信息在运行时不可用。如果添加了这个,我相信 DI 会支持它们(它已经在 Dart 中得到支持)。
如果您使用的是 TypeScript,我可以为您提供解决方案。
我没有使用 Angular 2.0,但我们开发了类似的 DI 库 (intakejs)。问题是 TS 编译器仅为 classes 发出反射元数据,而不是为接口发出反射元数据(它们被视为 "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:
class MyConsumer {
@Inject(IMyInjectable)
private myInjectable: IMyInjectable;
}
希望这个小技巧能解决你的问题。
我一直在阅读 Angular 2.0 docs about dependency inversion and I've been looking also at some online examples。
我的理解是 @injectable
装饰器使用带有 emitDecoratorMetadata
标志的 TypeScript 编译器来创建用于解析依赖项的元数据。以下面的例子 class:
TypeScript 编译器使用 emitDecoratorMetadata
通过元数据声明 DataService
class 具有类型为 Http
.
一旦我们使用 @Injectable
声明了 class 的依赖项,我们就可以使用 [=18= 中的 Provides
选项指示它需要被注入到某些组件中] 或 @Component
个装饰器。
我知道 emitDecoratorMetadata
的行为并且我知道它不能为接口发出元数据。因此,我假设我不能依赖 IHttp
而不是 Http
:
我的假设正确吗?我可以依赖 “Depend upon Abstractions. Do not depend upon concretions.” 还是目前不可能的事情?我认为一旦 emitDecoratorMetadata
能够序列化接口,这个问题就会得到解决。
目前您需要一个类型、一个字符串名称或一个 OpaqueToken
作为提供商的键。
不支持接口,因为信息在运行时不可用。如果添加了这个,我相信 DI 会支持它们(它已经在 Dart 中得到支持)。
如果您使用的是 TypeScript,我可以为您提供解决方案。
我没有使用 Angular 2.0,但我们开发了类似的 DI 库 (intakejs)。问题是 TS 编译器仅为 classes 发出反射元数据,而不是为接口发出反射元数据(它们被视为 "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:
class MyConsumer {
@Inject(IMyInjectable)
private myInjectable: IMyInjectable;
}
希望这个小技巧能解决你的问题。