假设我在app.config.ts里定义了一个interface AppConfig和一个对象HERO_DI_CONFIG, 我想将后者注入到一个类的构造函数里去:

export interface AppConfig {apiEndpoint: string;title: string;}import { InjectionToken } from '@angular/core';export const APP_CONFIG = new InjectionToken<AppConfig>('app.config');export const HERO_DI_CONFIG: AppConfig = {apiEndpoint: 'api.heroes.com',title: 'Dependency Injection'
};

使用InjectionToken新建一个token,类型参数为AppConfig,单引号里的app.config是injection token的描述信息。

在NgModule里使用useValue注入:

在需要使用这个依赖的地方,将token APP_CONFIG传入@Inject:

最后的效果:


在控制反转中,”控制“是指对程序流程的控制,”反转“则是将控制权从程序员的手里反转到了外层框架。

@optional修饰符

@Component({selector: 'app-notification',templateUrl: './notification.component.html',styleUrls: ['./notification.component.less']
})
export class NotificationComponent implements OnInit {constructor(@Optional() private msg: MessageService) {}ngOnInit() {this.msg.send();}
}

如果无法注入,msg被Angular解析成null,而不会抛出错误。

@Optional() 允许 Angular 将您注入的服务视为可选服务。这样,如果无法在运行时解析它,Angular 只会将服务解析为 null,而不会抛出错误

@Self

使用 @Self 让 Angular 仅查看当前组件或指令的 ElementInjector

@SkipSelf

使用 @SkipSelf(),Angular 在父 ElementInjector 中而不是当前 ElementInjector 中开始搜索服务

一个例子:在父组件中定义了一个服务:ParentMessageService

import { Injectable } from '@angular/core';@Injectable({providedIn: 'root'
})
export class ParentMessageService {constructor() {}send() {console.log('come from parent');}
}@Component({selector: 'app-container',templateUrl: './container.component.html',styleUrls: ['./container.component.less'],providers: [{ provide: MessageService, useClass: ParentMessageService }]
})
export class ContainerComponent implements OnInit {constructor() {}ngOnInit() {}
}

子组件中,我们已提供了服务,但是注入时使用了 @SkipSelf() 修饰符

@Component({selector: 'app-notification',templateUrl: './notification.component.html',styleUrls: ['./notification.component.less'],providers: [{provide: MessageService,useClass: NewMessageService}]
})
export class NotificationComponent implements OnInit {constructor(@SkipSelf() private msg: MessageService) {}ngOnInit() {this.msg.send();}
}

最终,Angular会注入父组件的服务实例:ParentMessageService

什么是 Angular 的 ElementInjector?

这个概念和 Angular 多级注入器有关。Angular creates ElementInjectors implicitly for each DOM element. Angular 会为每个 DOM 元素隐式创建 ElementInjector。

Providing a service in the @Component() decorator using its providers or viewProviders property configures an ElementInjector.

当我们在 Component 里定义 providers 时,我们就已经配置了一个 ElementInjector.

@Component({...providers: [{ provide: ItemService, useValue: { name: 'lamp' } }]
})
export class TestComponent

When you provide services in a component, that service is available via the ElementInjector at that component instance.

通过 ElementInjector,我们配置在 Component 里的服务,能够被组件实例使用到。

组件是一种特殊类型的指令,这意味着 @Directive() 具有 providers 属性,@Component() 也同样如此。 这意味着指令和组件都可以使用 providers 属性来配置提供者。当使用 providers 属性为组件或指令配置提供者时,该提供程商就属于该组件或指令的 ElementInjector。同一元素上的组件和指令共享同一个注入器。

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

Angular 通过依赖注入机制注入一个对象的例子,什么是 ElementInjector相关推荐

  1. Angular 4 依赖注入教程之一 依赖注入简介

    目录 Angular 4 依赖注入教程之一 依赖注入简介 Angular 4 依赖注入教程之二 组件服务注入 Angular 4 依赖注入教程之三 ClassProvider的使用 Angular 4 ...

  2. 如何在 Web Forms 中引入依赖注入机制

    依赖注入技术就是将一个对象注入到一个需要它的对象中,同时它也是控制反转的一种实现,显而易见,这样可以实现对象之间的解耦并且更方便测试和维护,依赖注入的原则早已经指出了,应用程序的高层模块不依赖于低层模 ...

  3. .NET平台依赖注入机制及IoC的设计与实现

    我们设计的分层架构,层与层之间应该是松散耦合的.因为是单向单一调用,所以,这里的"松散耦合"实际是指上层类不能具体依赖于下层类,而应该依赖于下层提供的一个接口.这样,上层类不能直接 ...

  4. .net core 注入机制与Autofac

    本来是要先出注入机制再出 管道 的,哈哈哈--就是不按计划来-- 这里扯扯题外话:为什么要注入(DI,dependency-injection),而不用 new 对象? 可能我们都很清楚,new 对象 ...

  5. 什么是IOC(控制反转)、DI(依赖注入)举个形象的例子通俗易懂

    更多免费教学文章请关注这里 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清 ...

  6. 【源码分析】Spring的循环依赖(setter注入、构造器注入、多例、AOP)

    写在前面 首先最简单的循环依赖demo就是:A->B 且 B->A.本文围绕这个例子去讲解setter注入的循环依赖.构造器注入循环依赖.多例的循环依赖.带AOP的循环依赖.以下是一些结论 ...

  7. Spring注入(Injection)——教你一点一点知道什么是依赖注入及注入方式

    前言 在学习spring的时候有个很重的知识点,那就是注入,不同的注入方式为程序的运行效率,资源利用都有不同的好处,接下来就看看我通过看视频总结的注入. 一.引入注入 1.首先我们明确一个问题,什么注 ...

  8. spring4.x(10)---依赖注入-构造方法注入

    依赖注入-构造方法注入 通过构造方法注入,就相当于给构造方法的参数传值. 一.编写CustomerDao接口 package com.yiidian.dao; /*** * @author http: ...

  9. 手写Spring-第四章-为依赖的对象注入灵魂!

    前言 经过了前面的三章,不知道大家有没有一个感觉,总觉得有些怀念Spring中我们最常用到的那个东西,但是等啊等啊,一直没有提到它.没错,就是我们的@Autowired!单丝不成线,孤木不成林.很多时 ...

最新文章

  1. 信号建模与参数估计作业重新计算
  2. Intel Realsense D400系列后面的盖子是干嘛用的?
  3. 拥抱智能,AI视频编码技术的新探索
  4. Problem A: 判断操作是否合法(栈和队列)
  5. 服务器开机忘记密码怎么修改,服务器忘记mysql密码怎么修改?
  6. 被腾讯看上,叽里呱啦获近亿美元C轮融资
  7. 算法导论 pdf_下载算法导论_高清_pdf
  8. html5 java 微信商城_微信商城和H5商城区别是什么?
  9. HTML期末大作业~ 仿新浪微博个人主页html网站模板4个页面(HTML+CSS+JavaScript)
  10. 微信小程序云开发源码(垃圾分类源码)
  11. 哪种硬盘坏道检测工具最好,有硬盘坏道怎么修复
  12. 不积跬步无以至千里013
  13. P3P求解相机姿态原理介绍
  14. tableau表计算--柏拉图曲线
  15. jssdk 获取微信收货地址_微信JSSDK获取当前地理位置信息
  16. compare用法java,Java经典用法总结
  17. 读Python源码(三)Python列表的表示
  18. go开源项目整理-新手篇_一周的前5篇文章:您正在从事什么开源项目?
  19. 全国排名前十技术大牛,被裁只要十分钟
  20. oracle数据库空间预警,数据库系统预警机制

热门文章

  1. C#Redis哈希Hashes
  2. Thinking In Java 第四章 控制执行流程
  3. 插件~NuGet与packages管理项目的包包
  4. 校园网搭建案例(课堂总结)
  5. 一个应用程序和另一个应用程序apk文件信息
  6. 今天是魔兽世界关服的日子
  7. 先装XP再装WIN2000双系统无法启动的解决办法
  8. oracle的学习笔记(转)
  9. plsql强制关闭后再打开提示已停止工作的解决办法
  10. [redis] 分布式 Redis 的 CRUD 实现