在 angular1 中,我们经常使用 factory 来注入类,而不是实例。在 angular2 中,我可以做同样的事情:
{provide: MyClass, useFactory: () => { return MyClass }}
...
constructor(MyClass) {
let instance = new MyClass();
}
但是,我记得读到这是由于缺少JS模块而合理的。现在我们使用 ES6 模块,我想知道是否需要使用 DI 进行类注入?我看到许多库不使用角度 DI 来获取类,而是通过import
语句访问它们。
{provide: MyClass, useFactory: () => { return MyClass }}
和
{provide: MyClass, useValue: MyClass }
本质上是一回事。是的,对应该手动实例化的类使用 DI 是有意义的。
当在JS(ES.下一篇):
constructor(@Inject(MyClass) MyClass) {
this.MyClass = new MyClass;
}
但是在 TypeScript 中使用可能不太方便,因为应该正确指定类型:
constructor(@Inject(MyClass) MyClass: typeof MyClass) {
this.MyClass = new MyClass;
}
将其作为提供程序可以随时替换或增强功能,而无需修补原始代码,这对于第三方库来说是一个很好的特征。
它提供了更好的可测试性,MyClass
可以用存根类或间谍功能代替。当不涉及 DI 时,这使得测试更加复杂,并且需要在导入级别实现 DI,例如使用rewire-webpack
。
您需要使用 TypeScript import 语句来使*.ts
文件中的类型已知。这与 DI 完全不同,与 DI 没有真正的关系,只是此类导入的类型可以用作请求依赖项的 DI 提供程序密钥。
您可以使用new MyClass()
创建类实例。
如果你的类有像 AngularsHttpModule
这样的依赖项Http
class MyClass {
constructor(this.http:Http) {}
}
使用 DI 很方便,因为您可以获取 DI 创建的MyClass
实例以及自动传入的Http
参数。
DI(控制反转)也是一种常见的编程模式,它使测试更容易,因为生成的类不是紧密耦合的。
DI 是分层的,可以轻松共享具有特定作用域的实例(例如组件实例及其所有子实例)