简体   繁体   English

Angular 2使用现有提供者

[英]Angular 2 useExisting providers

What are the usages for useExisting provider? 使用提供商的用法有useExisting

Is it useExistingOrThrowIfThereIsNone or useExistingOrCreateIfThereIsNone ? 它是useExistingOrThrowIfThereIsNone还是useExistingOrCreateIfThereIsNone Can one of these behaviours be chosen on purpose somehow, depending on our needs? 根据我们的需要,可以某种方式有目的地选择其中一种行为吗? If one of them is not supported, can an unsupported one be emulated? 如果其中一个不受支持,是否可以模拟不受支持的一个?

The documentation is totally unclear on that and just gives an example that useExisting can reuse an instance from useClass . 该文件是对完全不清楚,只是给出了一个例子useExisting可重用一个实例useClass

With this example 有了这个例子

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

If you have 如果你有

constructor(private a: A)

an instance for the first provider is created. 创建第一个提供程序的实例。

constructor(private b: B)

an instance for the 2nd provider is created 创建第二个提供程序的实例

constructor(private c: C)

the instance of the first provider is injected. 注入第一个提供者的实例。

If you start fresh with 如果你重新开始

constructor(private c: C)

an instance for the first provider is created and injected 创建并注入第一个提供程序的实例

When we write {provide: A, useClass: B} , Angular will create map between token A and class B . 当我们写{provide: A, useClass: B} ,Angular将在标记 A B之间创建映射。

When we write {provide: A, useExisting: B} , Angular will create map between token A and token B . 当我们写{provide: A, useExisting: B} ,Angular将在令牌 A令牌 B之间创建映射。

Difference between these maps: 这些地图之间的区别:

  • token A -> instance of class B 令牌A - > B类的实例
  • token A -> token B -> instance of some class for token B 令牌A - >令牌B - >令牌B的某个类的实例

Just small addition/clarification to @GünterZöchbauer's answer. 只是对@GünterZöchbauer的回答进行了一些补充/澄清。

It's actually useExistingOrThrowIfThereIsNone when we're talking about tokens . 当我们谈论令牌时,它实际上是使用ExistingOrThrowIfThereIsNone。 useExisting creates an alias to another token , not an instance , so there must be the token referred by useExisting, otherwise exception will be thrown. useExisting为另一个标记而不是实例创建别名,因此必须有useExisting引用的标记,否则将抛出异常。 But when we're talking about instances , it will work as long as last token in the chain registers instance , so in that sense it is useExistingOrCreateIfThereIsNone. 但是当我们讨论实例时 ,它只会在链寄存器实例中的最后一个标记中起作用,因此在这个意义上它是useExistingOrCreateIfThereIsNone。

Consider this: 考虑一下:

// 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: 

In this case second declaration will throw an error because token C refers to token A but there is no token A declared anywhere, even though there's an instance of class A in the injector. 在这种情况下,第二个声明将抛出一个错误,因为令牌 C引用了令牌 A但是没有任何令牌 A在任何地方声明,即使注入器中有一个A类实例 Angular will not attempt to create instance A for token C or associate token C with existing instance A. I just accidentally verified it in one of my projects. Angular不会尝试为令牌 C创建实例 A或将令牌 C与现有实例 A关联。我只是在我的一个项目中意外地验证了它。 :) :)

The following will work though because of reasons well described in other answers: 由于其他答案中描述的原因,以下内容将起作用:

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

In this example instance of A will be created for token C even if there was no instance A created previously for token B. So, for token C it is "use whatever instance should be provided for token B", and for token B it is "use existing instance A or create new if there's none". 在A的这个例子实例令牌 C下创建即使没有实例以前创建的令牌 B.因此,对于令牌 C时是“应该令牌 B时所提供的使用任何实例 ”,并为令牌 B检查是“如果没有,则使用现有实例 A或创建新实例 ”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM