Angular 2 useExisting providers

后端 未结 3 1455
旧巷少年郎
旧巷少年郎 2020-12-31 04:41

What are the usages for useExisting provider?

Is it useExistingOrThrowIfThereIsNone or useExistingOrCreateIfThereIsNone? Can o

相关标签:
3条回答
  • 2020-12-31 04:42

    Just small addition/clarification to @GünterZöchbauer's answer.

    It's actually useExistingOrThrowIfThereIsNone when we're talking about tokens. useExisting creates an alias to another token, not an instance, so there must be the token referred by useExisting, otherwise exception will be thrown. 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.

    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. 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. :)

    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".

    0 讨论(0)
  • 2020-12-31 04:44

    When we write {provide: A, useClass: B}, Angular will create map between token A and class B.

    When we write {provide: A, useExisting: B}, Angular will create map between token A and token B.

    Difference between these maps:

    • token A -> instance of class B
    • token A -> token B -> instance of some class for token B
    0 讨论(0)
  • 2020-12-31 05:03

    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

    0 讨论(0)
提交回复
热议问题