Angular 2 使用现有提供程序

Angular 2 useExisting providers

useExisting 提供商有什么用途?

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

文档对此完全不清楚,只是给出了一个示例,说明 useExisting 可以重用 useClass 中的实例。

以这个例子

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)

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

当我们写 {provide: A, useClass: B} 时,Angular 将在 token Aclass 之间创建映射 B.

当我们写 {provide: A, useExisting: B} 时,Angular 将在 token Atoken[=29= 之间创建映射] B.

这些地图之间的差异:

  • 令牌 A -> class B
  • 的实例
  • 令牌 A -> 令牌 B -> 某些 class 的实例用于令牌 B

@GünterZöchbauer 的回答只是 addition/clarification。

当我们谈论代币时,实际上是useExistingOrThrowIfThereIsNone。 useExisting 创建另一个 token 的别名,而不是 instance,因此 must 是引用的令牌useExisting,否则会抛出异常。但是当我们谈论 instances 时,只要链寄存器中的最后一个标记 instance,它就会工作,所以在这个意义上它是 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: 

在这种情况下,第二个声明将抛出错误,因为 token C 引用 token A 但没有 token A 在任何地方声明,即使注入器中有 class A 的 instance。 Angular 不会尝试为 token C 创建 instance A 或将 token C 与existing instance 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

在此示例中,将为 token C 创建 A 的 instance,即使没有 instance A 之前为 token B 创建。因此,对于 token C,它是 "use whatever instance should be provided for token B",对于 token B 是"use existing instance A or create new if there's none".