Angular: useClass vs useExisting?

When should we use use existing provider instead of useClass ?

providers: [
{provide: Class1, useClass: Class1}, 
{provide: Class2, useExisting: Class2}]

      


: I didn't find the exact question on SO. And for better indexing decided to create this particular one here, although I found answers to this:

but I would like to have more real examples

+3


source to share


3 answers


You usually get a copy for each provider.

{provide: Class1, useClass: Class1}, 

      

equivalent to just

Class1

      

FROM



{provide: Class1, useClass: Class3}, 

      

you can configure that when a constructor is requested, Class1

Angular DI creates an instance Class3

and passes it to the constructor.

{provide: Class2, useExisting: Class2}

      

does not result in an instantiation, but you can see this, not an alias. If the constructor asks Class2

, Angular DI looks for another provider for the key Class2

and injects an instance from that provider Class2

. You can see it useExisting

as a link to another vendor or an alias.

+8


source


Angular creates a factory for providers that will be used to instantiate the provider.

I usually use the following table to understand the difference between provider types.

enter image description here

As we can see in the figure above, all suppliers can be represented similarly useFactory

. When it's time to get an instance of the angular provider just calls the function factory

.

So for useClass

angular it resolves the dependency on an array of parameters and then calls the constructor with the parameters, and for useExisting

angular it gets the existing resolved instance and returns it.

Use cases:

1) Don't disclose full functionality

{ provide: PublicApi, useExisting: PrivateImpl }

{ provide: MinimalLogger, useExisting: LoggerService }

{ provide: PlatformRef, useExisting: PlatformRef_ }

{ provide: ApplicationRef, useExisting: ApplicationRef_}

{ provide: Sanitizer, useExisting: DomSanitizer },

{ provide: Compiler, useExisting: JitCompiler }

      



2) Assembly tree

{ provide: Parent, useExisting: forwardRef(() => TreeViewComponent) }

      

3) avoid circular dependency

{ provide: BaseComponent, useExisting: forwardRef(() => MyComponent) }

      

4) Provide general tokens

{ provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true }

{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EmailValidator),  multi: true }

{ provide: NgControl, useExisting: forwardRef(() => NgModel) }

{ provide: ControlContainer, useExisting: forwardRef(() => FormGroupDirective) }

{ provide: NG_VALUE_ACCESSOR, multi: true, useExisting: MyDatePickerComponent }

      

If we replace useExisting

with useClass

, then write the registration of a new instance of the class

+3


source


useExisting - create a refrence for service example here
useClass - create a new instance of service example here

-1


source







All Articles