【问题标题】:Hierarchical Injector and dependancy lifetime分层注入器和依赖寿命
【发布时间】:2016-04-25 22:01:47
【问题描述】:

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

上下文:

我的 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 { ... }

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

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

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

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

【问题讨论】:

    标签: angular angular2-routing


    【解决方案1】:

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

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

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

    当一个组件被创建时,一个新的子注入器被创建(并且在组件被销毁时也被销毁)

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

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

    结论

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

    【讨论】:

    • 来自Angular 2 Hierarchical DI docs。 “在一个特定的注入器中只能有一个服务类型的实例。但我们已经了解到,我们可以在应用程序组件树的不同级别运行多个注入器。这些注入器中的任何一个都可以有自己的服务实例。 "这都很好。我(错误地)认为注射器会以某种方式停留。您的评论“..destroyed with the component”)很重要。谢谢!
    【解决方案2】:

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

    因此,在您的情况下,您确实需要将服务添加为全局服务。这将使其成为“单例”。


    附加链接

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

    【讨论】:

    • 谢谢,“被组件破坏”部分是我所缺少的。我想知道 - 这是否记录在任何地方? thinkram.io 文章和 Angular 2 文档中似乎都没有提到它。
    • @RonaldZarīts 我不这么认为,但这是合乎逻辑的方式,因为否则你会在一个巨大的应用程序中得到大量的注射器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多