Angular useClass vs useExisting
什么时候应该使用Angular useClass vs useExisting,angular,dependency-injection,angular-di,Angular,Dependency Injection,Angular Di,什么时候应该使用useExisting提供程序而不是useClass providers: [ {provide: Class1, useClass: Class1}, {provide: Class2, useExisting: Class2}] 备注:我还没有找到关于这方面的确切问题。为了更好地索引,我决定在这里创建一个特定的索引,尽管我发现了以下答案: 但是希望有更多真实的例子通常每个提供者都有一个实例 {provide:Class1,useClass:Class1},
useExisting
提供程序而不是useClass
providers: [
{provide: Class1, useClass: Class1},
{provide: Class2, useExisting: Class2}]
备注:我还没有找到关于这方面的确切问题。为了更好地索引,我决定在这里创建一个特定的索引,尽管我发现了以下答案:
但是希望有更多真实的例子通常每个提供者都有一个实例
{provide:Class1,useClass:Class1},
等同于正义
Class1
与
{provide:Class1,useClass:Class3},
您可以配置,当构造函数请求Class1
Angular时,DI创建Class3
的实例并将其传递给构造函数
{provide:Class2,useExisting:Class2}
不会导致创建实例,但您可以看到它而不是别名。
如果一个构造函数请求Class2
,Angular DI会为keyClass2
寻找另一个提供程序,并从该Class2
提供程序中注入实例。
您可以看到
useExisting
,就像对另一个提供程序或别名的引用一样。为将用于实例化提供程序的提供程序创建工厂
我通常使用下表来理解提供者类型之间的差异
正如我们在上图中所看到的,所有提供者都可以呈现类似的useFactory
。当需要获取提供程序实例时,只需调用factory
函数
因此,对于useClass
angular,从参数数组中解析依赖项,然后使用参数调用构造函数;而对于useExisting
angular,则获取已解析的现有实例并返回它
用例:
1) 不要暴露全部功能
{provide:PublicApi,useExisting:PrivateImpl}
{provide:MinimalLogger,useExisting:LoggerService}
{提供:PlatformRef,使用现有:PlatformRef}
{提供:ApplicationRef,使用现有:ApplicationRef}
{提供:消毒剂,使用现有的:DOMSANTIZER},
{提供:编译器,使用现有:JIT编译器}
2) 建树
{provide:Parent,useExisting:forwardRef(()=>TreeViewComponent)}
3) 避免循环依赖
{provide:BaseComponent,useExisting:forwardRef(()=>MyComponent)}
4) 提供公共令牌
{提供:NG_验证器,使用现有的:禁止验证器指令,multi:true}
{提供:NG_验证程序,使用现有的:forwardRef(()=>EmailValidator),multi:true}
{提供:NgControl,使用existing:forwardRef(()=>NgModel)}
{提供:ControlContainer,useExisting:forwardRef(()=>FormGroupDirective)}
{provide:NG_VALUE_访问器,multi:true,useExisting:MyDatePickerComponent}
如果我们更换
useExisting
使用useClass
,然后我们将注册一个新的类实例useExisting-创建对服务的引用
useClass-创建新的服务实例这似乎是一个真实的例子,Gunter,我不明白他们在这里给出的关于使用
useExisting
而不是useClass
的解释。你能简化一下吗?@karthikaruna对我来说似乎很合理。我不知道是什么问题。useExisting
只是重定向到另一个提供者。Injectable
和provider
是两个不同的东西。可注入类是DI可以创建的实例,或可以传递给构造函数的提供的值。提供程序是DI维护的提供程序注册表中的一个条目,允许按键查找提供程序(键是构造函数参数、字符串或InjectToken
的类型)。提供程序还保存有关如何“创建”可注入值/实例的信息。DI查找提供者,提供者提供值,DI将值(可注入的实例或按原样提供的值)传递给构造函数。如果将MyClass
注册为提供者,这是{provide:MyClass,useClass:MyValue}的缩写形式
其中provide:MyClass
是可以找到提供者的密钥,而useClass:MyValue
是传递给提供者的一种策略,告知提供者应该为此密钥提供什么值useClass:MyValue
意味着“使用new MyClass(…)
”,useExisting:Foo
意味着需要咨询DI来查找Foo
的提供者,然后注入该提供者提供的值。非常感谢你回答我天真的问题,伙计!你太棒了!对于multi-providers构造,如果我忘记在某些提供程序条目中输入multi:true
,该怎么办?@GlennMohammad如果你忘记输入multi:true,它将覆盖以前注册的指令。@实际上,从Angular 6开始,它现在将抛出一个错误:“提供程序分析错误:对于令牌注入token \…”来说,混合多个和非多个提供程序是不可能的,所以这很简单!:)