Angular 2使用现有提供者

时间:2016-07-17 11:57:42

标签: javascript typescript angular angular2-services

useExisting提供商的用法是什么?

useExistingOrThrowIfThereIsNone还是useExistingOrCreateIfThereIsNone?根据我们的需要,可以某种方式有目的地选择其中一种行为吗?如果其中一个不受支持,是否可以模拟不受支持的一个?

文档完全不清楚,只是举例说明useExisting可以重用useClass中的实例。

3 个答案:

答案 0 :(得分:23)

使用此示例

providers: [
    A, 
    {provide: B, useClass: A}, 
    {provide: C, useExisting: A}]

如果你有

constructor(private a: A)

创建第一个提供者的实例。

constructor(private b: B)

创建第二个提供者的实例

constructor(private c: C)

注入第一个提供者的实例。

如果你重新开始

constructor(private c: C)

创建并注入第一个提供者的实例

答案 1 :(得分:4)

当我们写{provide: A, useClass: B}时,Angular会在令牌 A B之间创建地图。

当我们写{provide: A, useExisting: B}时,Angular会在令牌 A令牌 B之间创建地图。

这些地图之间的区别:

  • 令牌A - > B类的实例
  • 令牌A - >令牌B - >令牌B的某个类的实例

答案 2 :(得分:4)

对@GünterZöchbauer的答案进行简单的补充/澄清。

当我们谈论令牌时,它实际上是在使用ExistingOrThrowIfThereIsNone。 useExisting为另一个标记而不是实例创建别名,因此必须是useExisting引用的标记,否则将抛出异常。但是,当我们谈论实例时,只要链中的最后一个标记注册实例,它就会起作用,因此从这个意义上说它是useExistingOrCreateIfThereIsNone。

考虑一下:

// T = token, I = instance
providers: [
    {provide: B, useClass: A}, // T[B] => I[A]
    {provide: C, useExisting: A}] // T[C] => ??? - there's no T[A] declared

...
constructor(private a: B) {} // works
...
constructor(private a: C) {} // throws an exception: 

在这种情况下,第二个声明会引发错误,因为令牌 C指的是令牌 A但是没有声明令牌 A,甚至虽然注射器中有A类的实例。 Angular不会尝试为令牌 C创建实例 A或将令牌 C与现有实例 A关联起来A.我只是在我的一个项目中意外地验证了它。 :)

由于其他答案中有充分描述的原因,以下内容将有效:

providers: [
    {provide: B, useClass: A}, // T[B] => I[A]
    {provide: C, useExisting: B}] // T[C] => T[B] => I[A]

...

constructor(private a: B) {} // works
...
constructor(private a: C) {} // works

在此示例中,即使没有为令牌创建的实例 A,也会为令牌 C创建A的实例 B.因此,对于令牌 C,“使用任何实例应为令牌 B”提供,并为令牌 B“使用现有的实例 A或创建新的,如果没有”。