在他们的documentation中,他们使用以下FactoryProvider
示例来升级ajs服务:
import { HeroesService } from './heroes.service';
export function heroesServiceFactory(i: any) {
return i.get('heroes');
}
export const heroesServiceProvider = {
provide: HeroesService,
useFactory: heroesServiceFactory,
deps: ['$injector']
};
@NgModule({
imports: [
BrowserModule,
UpgradeModule
],
providers: [
heroesServiceProvider
],
/* . . . */
})
是否有任何理由不使用InjectionToken
来做到这一点,因此不必为每个需要使用的模块将其添加到providers
列表中在吗?
import { HeroesService } from './heroes.service';
import {inject, InjectionToken} from '@angular/core';
import {auto} from 'angular';
export const heroesServiceToken = new InjectionToken<HeroesService>('HeroesServices', {
providedIn: 'root',
factory() {
const $injector = inject('$injector' as any) as auto.IInjectorService;
const instance = $injector.get('heroes');
return instance as HeroesService;
}
});
...
import { HeroesService } from './heroes.service';
import {Inject} from '@angular/core';
class SomeComponent {
constructor(@Inject(heroesServiceToken) private heroesService: HeroesService) {
}
}
答案 0 :(得分:0)
InjectionToken
通常没有与之关联的值。当您需要使非令牌值可注入(即Interface
)时,它们很方便。我认为工厂的选项是在更高版本的Angular中添加的,一旦有了工厂,便有了令牌的关联值。因此,不应在providers数组中使用带有工厂的令牌。
我觉得该文档使用的是最常见的用例,并且更容易让人理解。
这样您不必将其添加到需要使用它的每个模块的提供者列表中吗?
那句话并不完全正确。
如果需要该模块提供,则将其添加到模块中的提供商中。当模块需要使用时,将注入提供程序,并通过找到提供它的父注入器来解析该值。将提供程序添加到 root 倾向于使所有人均可使用。
将提供程序插入 根可能很棘手。因此,Angular编译器会寻找注入以查看是否正在使用它,并且如果发现使用情况,编译后的应用程序会将其添加到provideIn
声明中。否则,我们必须手动提供它。
我说起来很棘手,因为编译器未获取诸如let thing = injector.get(myThing)
之类的源代码。我唯一知道编译器将看到的构造函数参数和@Inject()
。
使用带有令牌的工厂会隐藏该值的生命周期。除非有人去看一下令牌的声明位置,否则他们将不知道令牌是如何创建的。在模块中提供工厂较为常见,人们会看到它。
如果您需要在{em>工厂中使用provideIn
,那么我认为令牌是唯一的方法。