2017-02-20 67 views
2

在angular1中,我们经常使用工厂来注入类,而不是实例。在angular2中,我可以做同样的事情:使用DI进行类注入有什么意义吗

{provide: MyClass, useFactory:() => { return MyClass }} 

... 
constructor(MyClass) { 
    let instance = new MyClass(); 
} 

但是,我记得读到,这是由JS模块的缺席是合理的。现在我们使用ES6模块,我想知道是否需要使用DI进行类注入?我看到许多不使用角度DI获取类的库,但通过import语句访问它们。

回答

1
{provide: MyClass, useFactory:() => { return MyClass }} 

{provide: MyClass, useValue: MyClass } 

在本质上是一样的。是的,对于应该手动实例化的类使用DI是有意义的。

它创建时,DI在JS(ES.Next)不执行的问题:

constructor(@Inject(MyClass) MyClass) { 
    this.MyClass = new MyClass; 
} 

但由于类型应适当规定它可能是打字稿使用不太方便:

constructor(@Inject(MyClass) MyClass: typeof MyClass) { 
    this.MyClass = new MyClass; 
} 

让它作为提供者可以在不修补原始代码的情况下随时替换或增加功能,这是第三方库的一个很好的特性。

而且它提供了更好的可测性,MyClass可以用stub类或间谍功能所取代。当不涉及DI时,这使得测试更加复杂并且需要在导入级别上实施DI,例如,与rewire-webpack

+0

'{provide:MyClass,useValue:MyClass}'应该是'{provide:MyClass,useClass:MyClass}'或者'MyClass',可能''提供:MyClass,useFactory:()=> {返回MyClass}}'也被认为是'{提供:MyClass,useFactory:()=> {return new MyClass()}}' –

+0

@GünterZöchbauer,nope ,他的例子是正确的,他想提供一个类,而不是一个实例 –

+0

@GünterZöchbauer应该吗?在useValue的情况下,一个类被注入。在useClass的情况下,一个类实例被注入。 – estus

1

您需要使用打字稿import语句做出*.ts文件中已知的类型。这与DI完全不同,并且与DI没有真正的关联,只不过这种导入的类型可以用作DI提供者密钥来请求依赖关系。

您可以使用new MyClass()创建类实例。

如果你的类有来自Angulars HttpModuleHttp依赖就像使用DI是方便,因为你得到通过DI创建的MyClass实例,也是Http参数自动传递

class MyClass { 
    constructor(this.http:Http) {} 
} 

DI(反转控制)也是常见的编程模式,其使测试更容易,因为你的所得类不紧密耦合的。

DI是hiearchical并可以很容易地共享特定范围实例(例如一个组件实例和它所有的孩子)

+0

谢谢,_这与DI完全不同,并且与DI_无关 - 在anglular1中,这是向DI注入类的常见模式。所以我从你的答案中了解到,如果一个班级没有依赖关系,那么使用DI没有意义,对吗? –

+0

这也是相反的方式。如果其他课程取决于你的班级,DI也是有用的。如果您想共享具有不同组件,指令,管道或其他服务的实例,那么DI非常方便,因为DI需要注意特定实例的注入。注入类从Angular1中取代'$ scope'。另见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service和https://angular.io/docs/ts/latest/cookbook/dependency-injection。 html –

+0

是的,谢谢。不确定我是否清楚地表达了自己的问题,因为你在谈论实例,我正在上课。 _注入的类将从Angular1_中取代$ scope - 我们在angular1中使用了该模式以及:) –