使用类与使用现有

useClass vs useExisting

我们什么时候应该使用 useExisting 提供商而不是 useClass

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

REMARK: 我还没有找到关于 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 为将用于实例化提供程序的提供程序创建工厂。

我通常使用以下table来了解不同类型的提供商之间的区别。

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

所以 for useClass angular 从参数数组解析依赖关系,然后使用参数调用构造函数,而 for useExisting angular 获取现有的解析实例和 returns它。

用例:

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,然后我们将注册一个新的 class 实例

useExisting - 创建对服务的引用 example here
useClass - 创建新的服务实例 example here