分层注入器和依赖生命周期

Hierarchical Injector and dependancy lifetime

使用分层注入时,非根注入器中提供的依赖项的生命周期是多少?

上下文:

我的 Angular 2 应用程序由几个部分组成。在根组件中有一个 @RouteConfig,其中包含到组件 ABC 的路由。组件 B 有子部分 @RouteConfig 到子部分 xy

/A
/B
  /x
  /y
/C

组件 x 需要服务 q。按照 J. Papa's Angular 2 style guide 中的建议,我在组件 x 级别为注入器提供了服务,即

@xComponent({
    providers: [q]
})
export class xComponent { ... }

服务q在内部请求和缓存一些数据。我的印象是服务是单例的,在随后访问 /B/x 时,数据将从缓存中可用。但是,通过上述设置,每次用户打开 /B/x 部分时,都会再次请求数据。我在服务 q 的构造函数中放置了一个 console.log("creating q") 并看到每当访问 /B/x 时都会创建一个新的服务实例。

如果我在组件 /B 级别提供服务,则在 /B/x/B/y 之间导航时会缓存该值,但在导航至 /A 时会丢失该值] 或 /C.

似乎只要组件被销毁,注入器就会被销毁。这是预期的行为吗?

配置应用程序以免重新创建服务的正确方法是什么?显然我可以在根组件级别提供服务,但也许我遗漏了什么?

Angular2个团队成员多次强调DI维护的实例不是单例(他们认为单例不是太好的设计模式)

相反 Angular2 DI 为每个提供者维护一个实例。

Angular 还会创建一个类似于组件树的注入器树。

创建组件时,会为该组件创建一个新的子注入器(并在销毁组件时销毁)

子注入器从组件 providers: 列表中获取自己的一组提供程序。

如果子注入器找不到所请求密钥(令牌或类型)的提供者,它会将请求转发给父注入器。

结论

如果您想确保在您的应用程序中只创建一个服务实例,请将其注册到根组件的 providers: [...] 列表(建议)或 bootstrap(...)

您确实完全了解注射器的行为。它们被添加到那里的组件并被那里的组件销毁。

因此,在您的情况下,您确实需要将服务添加为全局服务。这将使它成为 "singleton"。


额外Link

如果你想了解更多关于angular2的依赖注入,我可以推荐这篇文章:http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html