Angular: useClass против useExisting?
Когда мы должны использовать провайдера useExisting вместо useClass?
providers: [
{provide: Class1, useClass: Class1},
{provide: Class2, useExisting: Class2}]
примечание: я не нашел точного вопроса по SO. И для лучшей индексации решил создать этот конкретный здесь, хотя я нашел следующие ответы:
- Angular 2 useExisting провайдеры
- Angular 2 - useValue против useFactory
- Angular 2 useExisting провайдеры
но хотелось бы иметь больше реальных примеров
3 ответа
Обычно вы получаете экземпляр для каждого поставщика.
{provide: Class1, useClass: Class1},
эквивалентно просто
Class1
С
{provide: Class1, useClass: Class3},
Вы можете настроить, что когда конструктор запрашивает Class1
Angular DI создает экземпляр Class3
и передает его конструктору.
{provide: Class2, useExisting: Class2}
не приводит к созданию экземпляра, но вы можете видеть это, а не псевдоним. Если конструктор запрашивает Class2
Angular DI ищет другого поставщика ключей Class2
и вставляет экземпляр из этого Class2
поставщик. Ты можешь видеть useExisting
как ссылка на другого поставщика или псевдоним.
Angular создает фабрику для провайдеров, которая будет использоваться для создания провайдера.
Я обычно использую следующую таблицу, чтобы понять разницу между типами провайдеров.
Как видно на картинке выше, все провайдеры могут быть представлены аналогично useFactory
, Когда пришло время получить экземпляр провайдера угловой только звонки factory
функция.
Таким образом, для useClass
angular разрешает зависимость от массива параметров, а затем вызывает конструктор с параметрами, в то время как для useExisting
angular получает существующий разрешенный экземпляр и возвращает его.
Случаи применения:
1) Не выставляйте полную функциональность
{ 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) Построить дерево
{ provide: Parent, useExisting: forwardRef(() => TreeViewComponent) }
3) Избегайте круговой зависимости
{ provide: BaseComponent, useExisting: forwardRef(() => MyComponent) }
4) Предоставьте общие токены
{ 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 }
Если мы заменимuseExisting
с useClass
тогда мы будем регистрировать новый экземпляр класса