注入服务的构造函数何时运行?

Posted

技术标签:

【中文标题】注入服务的构造函数何时运行?【英文标题】:When does the constructor of an injected service in angular run? 【发布时间】:2019-04-25 22:42:03 【问题描述】:

在 Angular 7 中,如果我们有一个声明为 @Injectable(providedIn: 'root') 的服务,它的构造函数什么时候执行?它是在构建使用它的组件(作为依赖项)时执行,还是等到该服务中的方法第一次被调用?

注意: 由于服务是单例的,所以我使用服务的构造函数来初始化一些值。我可以创建一个“Initialize()”方法并在组件的构造函数中调用它,但我发现这种方法有点混乱。

【问题讨论】:

最迟在注入组件时,但可能更早(实现细节)。 服务实例在注入时创建。如果你不注入它们,它们什么也不做,在你的最终构建中,它们将被摇树。 你为什么不直接测试一下? 我是,但由于某种原因行为不一致。首次加载路由时,它不会触发服务的构造函数,但是当我刷新浏览器时它会触发! @sdagkas 我也遇到了这种行为 【参考方案1】:

使用Injectable 装饰器装饰的类的构造函数在某个范围的注入器初始化该类/服务时被调用。您不能在一个范围内拥有同一服务的多个实例,除非您通过 provide: MyService, useClass: MyService, multi: true 提供服务来强制它。

provideIn 选项定义了服务所属的范围,因此使用provideIn: 'root' 告诉 DI 使用 RootInjector 注入服务。而且由于服务不会在一个范围内多次初始化,因此该服务的构造函数只被调用一次,当 DI 需要第一次将该服务注入另一个组件/服务/模块时。

【讨论】:

我有一种情况,注入服务的组件构造正常,但是服务的构造函数却没有运行。虽然服务的方法运行正常,但我可以从组件中调用它们,它们可以正常工作。 服务实例是在第一次需要它们的时候创建的。当一个组件(或另一个服务)需要一个服务时,角度扫描依赖注入树,并寻找一个定义(和一个服务的实例)。如果没有找到注入服务的实例,Angular 会创建一个注入服务的实例,然后才会运行注入服务的构造函数。【参考方案2】:

如果不知道您的组件和服务的范围,很难准确判断,但我会告诉您一个在这种情况下应该对您有所帮助的示例:

在我们的应用程序中,我们有一个完整的模块,专门用于在应用程序的另一部分中单击该数据时为特定数据位切换 mat-dialogs。

我们的应用程序组件在它的构造函数中初始化了一个简单的服务,名为 dialog-toggle。 Dialog Toggle 永远不会在其他任何地方调用。在 dialog-toggle 的构造函数中,它只是侦听一个 observable,告诉它何时应该发送消息以触发不同的对话框。

为了让这个服务触发它的构造函数,我们所要做的只是在我们的应用组件的构造函数中引用它。因为它在应用程序组件中,所以无论路由或导航如何,它每次都会触发,这正是我们的案例所需要的。

长话短说,我会看看您所引用的实际组件何时被初始化与您提供服务的时间。如果你在更高阶的模块中引用了它,那么构造函数很可能已经被触发了。

【讨论】:

【参考方案3】:

注入服务的实例是在第一次创建需要它们的组件时创建的,或者是在第一次实例化另一个需要它们的服务时创建的。

当创建(或实例化)需要将服务作为依赖项的组件(或其他服务)时,Angular 会扫描依赖注入树,并查找定义(和注入服务的实例)。如果没有找到注入服务的实例,Angular 会创建一个注入服务的实例,然后它的构造函数才会运行。

在创建需要它的对象(或其他服务)之前实例化服务的另一种方法是将其作为依赖项添加到 deps 数组中的 APP_INITIALIZER 中,如下所示:

 provide: APP_INITIALIZER, useFactory: () => () => null, deps: [MyService], multi: true 

这将在应用初始化时创建MyService 的实例,而不管何时创建需要它的其他组件/服务。 更多详情here.

【讨论】:

以上是关于注入服务的构造函数何时运行?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 NGRX 而不是构造函数注入服务?

使用 Quartz.NET 和 Simple Injector 进行构造函数注入

具有不可注入参数的服务和通用类的 Blazor 构造函数注入 [重复]

WCF 服务可以有构造函数吗?

NestJS - 在构造函数中未定义注入的服务

Prism:在无参数构造函数中注入服务