同 Angular service 的单例个性不同,Angular 组件和指令通常会被屡次实例化,比方 HTML markup 中每呈现一次 Component 的 selector,就会触发 Component 的一次实例化。
这些 Component 和 Directive 的范畴,仅限于导入它们的 NgModule,以避免命名抵触,例如两个组件可能具备雷同的选择器。正是因为 Angular 依赖注入 (DI) 行为的这种差别,须要将蕴含组件和指令的 NgModule 与蕴含组件、指令和 Providers
的 ModuleWithProviders 辨别开来,这就是 forRoot() 办法的用武之地。
然而,依赖注入并不总是这么简略。有时在疏导过程中,所有应用程序的 NgModule 都不可用。提早加载就是这样一个例子。当在路由期间提早加载 NgModule 时,在提早加载的 NgModule 中注册的 providers
,提供程序及其子项在疏导过程中不可用,此时 Angular 无奈注册它们。因而,它们仅在加载路由时才作为 providers 增加,而且它们的 作用域
是从提早加载的 NgModule 及其子模块开始注入。
如果有多个提早加载的 NgModule 尝试注册雷同的提供程序,则 NgModule 树的每个节点都会以不同的实例完结。通过在根目录导入提供程序,它有助于确保所有提早加载的 NgModule 都取得雷同的提供程序实例,这也是为什么 forRoot() 被这样命名的起因。
作为消费者,当应用层序里应用到的某个库依赖项须要一个提早加载的 NgModule 时,就须要调用其 forRoot 办法。在应用程序的根目录导入模块并应用 forRoot() 办法注册,以全局导入提供程序。在其余 NgModules 中,当须要导入组件和指令时,应用适当的非根模式的导入。