使用类与使用现有
useClass vs useExisting
我们什么时候应该使用 useExisting
提供商而不是 useClass
?
providers: [
{provide: Class1, useClass: Class1},
{provide: Class2, useExisting: Class2}]
REMARK: 我还没有找到关于 SO 的确切问题。为了更好的索引,我决定在这里创建这个特定的索引,尽管我找到了这个答案:
- useValue vs useFactory
但希望有更多真实的例子
通常您会为每个提供商获得一个实例。
{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 }
如果我们更换
useExisting
和 useClass
,然后我们将注册一个新的 class 实例
useExisting - 创建对服务的引用 example here
useClass - 创建新的服务实例 example here
我们什么时候应该使用 useExisting
提供商而不是 useClass
?
providers: [
{provide: Class1, useClass: Class1},
{provide: Class2, useExisting: Class2}]
REMARK: 我还没有找到关于 SO 的确切问题。为了更好的索引,我决定在这里创建这个特定的索引,尽管我找到了这个答案:
- useValue vs useFactory
但希望有更多真实的例子
通常您会为每个提供商获得一个实例。
{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 }
如果我们更换
useExisting
和 useClass
,然后我们将注册一个新的 class 实例
useExisting - 创建对服务的引用 example here
useClass - 创建新的服务实例 example here