Angular官方文档

Specifying a provider token

If you specify the service class as the provider token, the default behavior is for the injector to instantiate that class with new.
In the following example, the Logger class provides a Logger instance.

providers: [Logger]

NgModule的providers区域里,指定provider token. 如果将一个服务类直接指定成provider token,默认的行为就是,injector直接用new来初始化那个类。

上面的例子,会触发Logger的构造函数。等价于:

[{ provide: Logger, useClass: Logger }]

这个完整的声明在Angular官方文档里称为expanded provider configuration, 是一个包含两个属性的对象。

  • The provide property holds the token that serves as the key for both locating a dependency value and configuring the injector.

provide属性包含一个token,用于定位一个dependency value和配置injector.

  • The second property is a provider definition object, which tells the injector how to create the dependency value. The provider-definition key can be useClass, as in the example. It can also be useExisting, useValue, or useFactory. Each of these keys provides a different type of dependency, as discussed below.

第二个属性是一个provider定义对象,告诉injector如何创建dependency value. 这个定义可以是useClass,useExisting,useValue,或者useFactory.

一些例子:

[{ provide: Logger, useClass: BetterLogger }]

当使用Logger token时,injector返回BetterLogger的实例。

Aliasing class providers

To alias a class provider, specify the alias and the class provider in the providers array with the useExisting property.

In the following example, the injector injects the singleton instance of NewLogger when the component asks for either the new or the old logger. In this way, OldLogger is an alias for NewLogger.

下列的配置,会导致Component需要使用OldLogger时,会返回NewLogger的singleton实例。当然,如果请求NewLogger,亦会返回NewLogger实例。因此这种情形下,OldLogger是NewLogger语义层面的alias.

[ NewLogger,// Alias OldLogger w/ reference to NewLogger{ provide: OldLogger, useExisting: NewLogger}]

如果使用如下命令行创建 service:

ng generate service User

自动生成的代码:

import { Injectable } from '@angular/core';@Injectable({providedIn: 'root',
})
export class UserService {}

现在,你就可以在应用中到处注入 UserService 了。

该服务本身是 CLI 创建的一个类,并且加上了 @Injectable() 装饰器。默认情况下,该装饰器是用 providedIn 属性进行配置的,它会为该服务创建一个提供者。在这个例子中,providedIn: ‘root’ 指定 Angular 应该在根注入器中提供该服务。

当你把服务提供者添加到应用的根注入器中时,它就在整个应用程序中可用了。 另外,这些服务提供者也同样对整个应用中的类是可用的 —— 只要它们有供查找用的服务令牌。

你应该始终在根注入器中提供这些服务 —— 除非你希望该服务只有在消费方要导入特定的 @NgModule 时才生效。

也可以规定某个服务只有在特定的 @NgModule 中提供。比如,如果你希望只有当消费方导入了你创建的 UserModule 时才让 UserService 在应用中生效,那就可以指定该服务要在该模块中提供:

import { Injectable } from '@angular/core';
import { UserModule } from './user.module';@Injectable({providedIn: UserModule,
})
export class UserService {}

上面的例子展示的就是在模块中提供服务的首选方式。之所以推荐该方式,是因为当没有人注入它时,该服务就可以被摇树优化掉。如果没办法指定哪个模块该提供这个服务,你也可以在那个模块中为该服务声明一个提供者。

服务是一个广义的概念,它包括应用所需的任何值、函数或特性。狭义的服务是一个明确定义了用途的类。它应该做一些具体的事,并做好。

Angular 把组件和服务区分开,以提高模块性和复用性。 通过把组件中和视图有关的功能与其它类型的处理分离开,你可以让组件类更加精简、高效。

理想情况下,组件的工作只管用户体验,而不用顾及其它。 它应该提供用于数据绑定的属性和方法,以便作为视图(由模板渲染)和应用逻辑(通常包含一些模型的概念)的中介者。

组件应该把诸如从服务器获取数据、验证用户输入或直接往控制台中写日志等工作委托给各种服务。通过把各种处理任务定义到可注入的服务类中,你可以让它被任何组件使用。 通过在不同的环境中注入同一种服务的不同提供者,你还可以让你的应用更具适应性。

当 Angular 创建组件类的新实例时,它会通过查看该组件类的构造函数,来决定该组件依赖哪些服务或其它依赖项。 比如 HeroListComponent 的构造函数中需要 HeroService:

constructor(private service: HeroService) { }

当 Angular 发现某个组件依赖某个服务时,它会首先检查是否该注入器中已经有了那个服务的任何现有实例。如果所请求的服务尚不存在,注入器就会使用以前注册的服务提供者来制作一个,并把它加入注入器中,然后把该服务返回给 Angular。

是否创建新的依赖服务实例,取决于 provider 的具体类型。

当所有请求的服务已解析并返回时,Angular 可以用这些服务实例为参数,调用该组件的构造函数。

HeroService 的注入过程如下所示:从应用的 Injector 里获取 HeroService 实例。

提供服务

对于要用到的任何服务,你必须至少注册一个提供者。服务可以在自己的元数据中把自己注册为提供者,这样可以让自己随处可用。或者,你也可以为特定的模块或组件注册提供者。要注册提供者,就要在服务的 @Injectable() 装饰器中提供它的元数据,或者在 @NgModule() 或 @Component() 的元数据中。

默认情况下,Angular CLI 的 ng generate service 命令会在 @Injectable() 装饰器中提供元数据来把它注册到根注入器中。本教程就用这种方法注册了 HeroService 的提供者:

@Injectable({providedIn: 'root',
})

什么是 Angular 依赖注入的 tree-shaking

When you provide the service at the root level, Angular creates a single, shared instance of HeroService and injects it into any class that asks for it. Registering the provider in the @Injectable() metadata also allows Angular to optimize an app by removing the service from the compiled app if it isn’t used, a process known as tree-shaking.

当你使用特定的 NgModule 注册提供者时,该服务的同一个实例将会对该 NgModule 中的所有组件可用。要想在这一层注册,请用 @NgModule() 装饰器中的 providers 属性:

@NgModule({providers: [BackendService,Logger],...
})

当你在组件级注册提供者时,你会为该组件的每一个新实例提供该服务的一个新实例。 要在组件级注册,就要在 @Component() 元数据的 providers 属性中注册服务提供者。

@Component({selector:    'app-hero-list',templateUrl: './hero-list.component.html',providers:  [ HeroService ]
})

Angular 依赖注入的学习笔记相关推荐

  1. .NET 云原生架构师训练营(模块二 基础巩固 依赖注入)--学习笔记

    2.2.1 核心模块--依赖注入 什么是依赖注入 .NET Core DI 生命周期 服务设计 服务范围检查 ASP.NET Core 依赖注入:https://docs.microsoft.com/ ...

  2. ASP.NET Core快速入门(第3章:依赖注入)--学习笔记

    点击蓝字关注我们 课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务16:介绍 1.依赖注入概念详解 从UML和软件建模来理 ...

  3. Angular 依赖注入学习笔记之工厂函数的用法

    网址:https://angular.institute/di We can transfer any data through our apps, transform it and replace ...

  4. angular依赖注入_Angular依赖注入简介

    angular依赖注入 by Neeraj Dana 由Neeraj Dana In this article, we will see how the dependency injection of ...

  5. java 构造器注入_Spring学习笔记1—依赖注入(构造器注入、set注入和注解注入)...

    什么是依赖注入 在以前的java开发中,某个类中需要依赖其它类的方法时,通常是new一个依赖类再调用类实例的方法,这种方法耦合度太高并且不容易测试,spring提出了依赖注入的思想,即依赖类不由程序员 ...

  6. Angular 依赖注入

    问题描述 初学Angular,可能对一堆注解有些懵. 我们一起通过实例来探讨Angular的依赖注入. 一路尝试 @Injectable 一个命令建的StockService,一个手动建的TestSe ...

  7. Angular 服务器端渲染的学习笔记(二)

    官网地址:https://angular.io/guide/universal I have mainly used angular universal for SEO purposes. In th ...

  8. Angular依赖注入的一个例子和注入原理单步调试

    定义一个抽象服务类: export abstract class GreetingService {abstract greet(name: string): string;} 定义一个具体类实现该抽 ...

  9. ASP.NET CORE 第四篇 依赖注入IoC学习 + AOP界面编程初探

    原文作者:老张的哲学 更新 1.如果看不懂本文,或者比较困难,先别着急问问题,我单写了一个关于依赖注入的小Demo,可以下载看看,多思考思考注入的原理: https://github.com/anjo ...

最新文章

  1. DDL、DML、DCL的理解
  2. 计算机没有autoCAD_挑战在一年内用晚上业余时间学会灵活运用CAD(1)|cad|autocad|图学|计算机|电子电路...
  3. 不进化,则消亡——互联网时代企业管理的十项实践
  4. 深度学习 占用gpu内存 使用率为0_深度学习的完整硬件指南
  5. unknown column in field list_tf.feature_column的特征处理探究
  6. 谈论源码_为什么每个人都在谈论WebAssembly
  7. 哈斯(Hasse)图
  8. 计算机病毒教学评课,计算机病毒评课稿.docx
  9. 求大于3的素数c语言,c语言判断一个大于3的数是否是素数
  10. HTML数据可视化散点图,数据可视化:用散点图进行数据分析
  11. a5m2使用方法 mysql_反転
  12. html表单 多行输入文字,如何在HTML中创建多行文本输入(文本区域)?
  13. 设备选型的重要性分析
  14. 上面两点下面一个三角形_三角形光栅化
  15. linux查显卡型号_Windows/Linux下怎么查看笔记本显卡型号
  16. excel修复后数据丢失_如何修复Excel数据栏
  17. 如何修改pdf格式文件
  18. hw3-空间与运动作业
  19. 机器人示教编程与离线编程的选择
  20. (Linux)SVN客户端查看及重置账号密码

热门文章

  1. 一个应用程序和另一个应用程序apk文件信息
  2. [蛋蛋の插画日记]囧...居然漏了一期《可爱100》!
  3. 从零写一个编译器(八):语义分析之构造符号表
  4. 互联网支付系统概要设计
  5. 博客园屏蔽广告CSS
  6. web browser 发展史
  7. Android中JNI的使用方法
  8. TeXworks 0.4.5 发布,TeX 编辑器
  9. 发布一个WTL实现的QQ2009登录窗口源码
  10. 用apksigner进行批量签名的脚本