24

我们什么时候应该使用useExistingprovider 而不是useClass

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

备注:我还没有找到关于 SO 的确切问题。为了更好的索引决定在这里创建这个特定的索引,尽管我找到了这个答案:

但希望有更多真实的例子

4

3 回答 3

34

useExisting - 在此处创建对服务示例的
引用 useClass - 在此处创建服务示例的新实例

于 2018-05-09T22:21:50.927 回答
28

通常,您会为每个提供者获得一个实例。

{provide: Class1, useClass: Class1}, 

相当于只是

Class1

{provide: Class1, useClass: Class3}, 

您可以配置,当构造函数请求Class1Angular DI 时创建一个实例Class3并将其传递给构造函数。

{provide: Class2, useExisting: Class2}

不会导致创建实例,但您可以看到它而不是别名。如果构造函数请求Class2,Angular DI 会寻找另一个提供者的密钥Class2并从这个提供者注入实例Class2。您可以看到useExisting对另一个提供者或别名的引用。

于 2017-07-17T20:29:35.940 回答
20

Angular 为提供者创建工厂,用于实例化提供者。

我通常使用下表来了解提供程序类型之间的区别。

在此处输入图像描述

正如我们在上面的图片中看到的,所有提供者都可以呈现类似的形式 useFactory。当是时候获取提供者角度的实例时,只需调用factory函数。

因此 for useClassangular 从参数数组中解析依赖关系,然后使用参数调用构造函数,而 for useExistingangular 获取现有的已解析实例并返回它。

用例:

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 }

如果我们替换 useExistinguseClass,那么我们将注册一个新的类实例

于 2017-07-17T21:30:26.150 回答