我们什么时候应该使用useExisting
provider 而不是useClass
?
providers: [
{provide: Class1, useClass: Class1},
{provide: Class2, useExisting: Class2}]
备注:我还没有找到关于 SO 的确切问题。为了更好的索引决定在这里创建这个特定的索引,尽管我找到了这个答案:
但希望有更多真实的例子
我们什么时候应该使用useExisting
provider 而不是useClass
?
providers: [
{provide: Class1, useClass: Class1},
{provide: Class2, useExisting: Class2}]
备注:我还没有找到关于 SO 的确切问题。为了更好的索引决定在这里创建这个特定的索引,尽管我找到了这个答案:
但希望有更多真实的例子
通常,您会为每个提供者获得一个实例。
{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
函数。
因此 for useClass
angular 从参数数组中解析依赖关系,然后使用参数调用构造函数,而 for 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
,那么我们将注册一个新的类实例