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 A
和 class 之间创建映射 B
.
当我们写 {provide: A, useExisting: B}
时,Angular 将在 token A
和 token[=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".
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 A
和 class 之间创建映射 B
.
当我们写 {provide: A, useExisting: B}
时,Angular 将在 token A
和 token[=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".