useClass vs useExisting
useExisting - create refrence to service example here
useClass - create new instance of service example here
Normally you get an instance per provider.
{provide: Class1, useClass: Class1},
is equivalent with just
Class1
With
{provide: Class1, useClass: Class3},
you can configure, that when a constructor requests Class1
Angular DI creates an instance of Class3
and passes it to the constructor.
{provide: Class2, useExisting: Class2}
doesn't result in an instance being created, but you can see this rather than an alias.
If a constructor requests Class2
, Angular DI looks for another provider for key Class2
and injects the instance from this Class2
provider.
You can see useExisting
like a reference to another provider or an alias.
Angular creates factory for providers that will be used to instantiate provider.
I usually use the following table to understand the difference between types of providers.
As we can see in the picture above all of providers can be presented similar useFactory
. When it's the time to get an instance of provider angular just calls factory
function.
So for useClass
angular resolves dependency from parameters array and then calls constructor with parameters while for useExisting
angular gets existing resolved instance and returns it.
Use cases:
1) Don't expose full functionallity
{ 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) Build tree
{ provide: Parent, useExisting: forwardRef(() => TreeViewComponent) }
3) Avoid circular dependency
{ provide: BaseComponent, useExisting: forwardRef(() => MyComponent) }
4) Provide common 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 we’d be registering a new class instance