Angular 6 providedIn - 如何为依赖注入定制 @Injectable() 的提供者?

13
在Angular 5中,如果我有一个扩展了抽象类的AbstractClassServiceExtendedClassService,我可以在NgModule的providers数组中执行以下操作:
@NgModule({
  providers: [
    {provide: AbstractClassService, useClass: ExtendedClassService}
  ]
})
export class AppModule {}

这将使我能够轻松地在测试或其他情况下切换ExtendedClassService。尽管在Angular 6中仍然可以实现这一点,但是有一个新的providedIn选项,可以在服务本身中设置以减少捆绑大小。
@Injectable({providedIn: 'root'})
export class ExtendedClassService extends AbstractClassService {}

在使用新的 providedIn 的同时,是否有一种方法可以实现我在Angular 5中实现的相同功能?就像这样:

@Injectable({providedIn: 'root', provide: AbstractClassService})
export class ExtendedClassService extends AbstractClassService {}

providedIn 只是用于定位注入器,该注入器将负责注入 ExtendedClassService 类的实例。对于此操作,它将使用根注入器。如果您不想使用根注入器,则可以指定任何其他模块。然后,服务实例将由包含该模块的注入器创建。 - Niladri
你可以使用 useFactory 来提供一个工厂函数,负责在需要动态创建实例时进行创建。 - Niladri
2
我认为在新的TreeShakable提供程序创建语法(provideIn)中,不可能为现有提供程序提供替代实现... 请查看此博客,它已经涵盖了大部分内容http://www.softwarearchitekt.at/post/2018/05/06/the-new-treeshakable-providers-api-in-angular-why-how-and-cycles.aspx - Abinesh Devadas
@Niladri,我确实希望根注入器负责注入服务,但我希望它使用令牌AbstractClassService——因为这是在组件中注入的内容——而不是ExtendedClassService - BeetleJuice
1个回答

14

我需要做两件事。

首先,在创建继承类时使用implements而不是extends,并不要在那里使用providedIn键:

@Injectable() // removed providedIn
export class ExtendedClassService implements AbstractClassService {}

第二步,将提供程序指令添加到抽象类中:

@Injectable({providedIn: 'root', useClass: ExtendedClassService})
export abstract class AbstractClassService {}

其他提供程序配置(useValue, useExisting, useFactory)也可以在那里使用。

感谢Abinesh的这个评论,它引导我找到了链接的博客文章。非常感谢博客作者!


1
如果ExtendedClassService有任何依赖项,例如HttpClient,它们必须添加到AbstractClassService装饰器中:deps: [HttpClient] - Drenai
1
如果您将服务放在单独的文件中,这将产生循环引用。非常令人恼火。 - EvAlex
1
如果基类不是我们自己的,比如说 Angular 核心中的 ErrorHandler 类,该怎么办? - Stephane
@EvAlex。如果你在不同的文件中只导出/导入类名,就可以避免循环引用(依赖关系)。如果你试图共享变量或枚举,你将会得到循环引用。我曾经遇到过这个问题,并通过将任何共享变量移动到单独的文件中来解决它。(在我的情况下,我只是将一个枚举移到了它自己的文件中)。 - samneric
@DmytroMezhenskyi 感谢您的提示,也许您需要它是因为特定的Angular版本或自从ivy以来。我看到了这个变化 https://angular.io/guide/migration-undecorated-classes ,但他们只提到了指令和组件,没有提到可注入对象。 - bersling
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接