前言

问题起因是因为在GriderService中遗记给根模块提供注入。
即没有写

@Injectable({  providedIn: 'root'})

手动注入

过后想着,能不能单纯在组件中应用provide GriderService使这个组件失常用service提供的服务.就像上面这样:

providers: [        {          provide: GriderService        }      ]

但事实上可行性不大。
因为GriderService的函数中同样须要依赖注入HttpClient,如下

constructor(protected httpClient: HttpClient) { }

所以,手动注入GriderService须要先手动注入HttpClient

所以我尝试着手动注入了HttpClient。并且如果new一个HttpClient的话,须要先new一个HttpHandler,这是Httpclient的构造函数所须要的。或者我应该这么做:

   let httpHandler = new HttpHandler();   let httpClient = new HttpClient(httpHandler);

然而,实际上HttpHandler是抽象类,并不能被实例化。

最初没胜利,并且在google上查找也没有比依赖注入更不便的了。我的确应该应用依赖注入。DI是 Angular 中的一个基本概念,也是使该框架如此有用的起因之一。

依赖注入

@Injectable() 装璜器标识服务类。该 providedIn 属性配置指定的 ModuleInjector,这里的 root 会把让该服务在 root ModuleInjector 上可用

长处

@Injectable() 的 providedIn 属性优于 @NgModule() 的 providers 数组,不仅在于它方便快捷,还因为应用 @Injectable() 的 providedIn 时,优化工具能够进行摇树优化(Tree Shaking)简略说就说通过Tree Shaking,不该留在代码中的多余代码,则会被摇掉

root

root 实际上是 AppModule 的别名,示意根模块,咱们因而不须要额定导入 AppModule,所有的模块原则上都属于根模块的子模块,所以所有的子模块都能够无条件的应用root根模块上的资源

对于注射器

在 root ModuleInjector 之上还有两个注入器,一个是额定的 ModuleInjector,一个是 NullInjector()

为了了解这张图,先大抵理解一下从angular启动。

angular启动

每一个 Angular 利用都以 main.ts 文件作为终点。(main.cs目前位于我的项目的src文件夹下,与app文件夹是同一级)

main.cs中最要害的是这两行代码:

1.platformBrowserDynamic() 办法创立一个由 PlatformModule 配置的注入器,简略来说就是浏览器平台的工厂函数,执行会返回浏览器平台的实例

2.bootstrapModule() 办法会创立一个由 AppModule 配置的注入器作为平台注入器的子注入器。也就是 root ModuleInjector

3.同时bootstrapModule启动app文件夹下的AppModule后,Angular 会去查看模块 AppModule 的 bootstrap 属性,该模块是用来启动程序的:

@NgModule({  imports: [BrowserModule],  declarations: [AppComponent],  bootstrap: [AppComponent]})export class AppModule {}

依赖注入服务流程

大抵了解了启动流程之后,咱们再联合方才那张图来看就很好了解了。

1.platformBrowserDynamic创立一个由 PlatformModule 配置的注入器Modele Injector。该注入器蕴含特定平台的依赖项

2.应用bootstrapModule办法,创立root ModeleInjector。

3.root ModeleInjector启动之后。若某个service能够给root提供服务,即
该service依赖注入root,root模块就能够应用该service提供的服务

图例

至于最顶层的NullInjector(),它是树的顶部。如果你在树中向上走了很远,以至于要在 NullInjector() 中寻找服务,那么除非应用 @Optional(),否则将收到谬误音讯,因为最终所有货色都将以 NullInjector() 完结并返回谬误