依赖注入(Dependency injection,DI)
为什么要使用依赖注入
没有使用依赖注入版本的实例Car:
export class LearnComponent {
public engine: Engine
public tries: Tries
public description = 'NO DI'
constructor() {
this.engine = new Engine()
this.tires = new Tires()
}
drive() {
return `${this.description} car with
${this.engine.cylinders} and
${this.tires.make}tires
`
}
}
特点是可扩展性很低,如果以后有一个新的Engine,Tires类,并不能在原有类的基础上扩展。再看依赖注入版本:
export class LearnComponent{
public description = "DI"
constructor(public engine:Engine,public tires:Tries){
}
}
let car = new car(new Engine(),new Tries())
上面代码中,public操作符做了3个工作
- 声明了构造函数的参数及其类型
- 创建一个与构造函数参数同名的属性
- 当该实例创建是,把构造函数参数赋值给同名属性
但是这样明显有些繁琐,依赖注入框架的工作就是让你不需要组装零件,直接使用Car实例。
angular2依赖注入组成部分:
- Injector 会被实例依赖的注入对象
- Provider 告诉Injector如何创建依赖
- Dependency 创建对象
在组件内注册依赖
import {Component} from '@angular/core'
//导入需要注入的依赖
import {HeroService} from './hero.service'
@Component({
selector:'app-learn',//css selector选择器,明确该组件应该加载到index.html的app-learn标签中
providers:[HeroService],//提供依赖流程
})
export class LearnComponent{
constrcutor(heroService:HeroService){
//heroService可以调用HeroService中的方法和属性
this.heroService...
}
}
由于injector提供的注入依赖都是单例实例,所以组件之间可以通过依赖共享操作过的数据。
下游使用的DI实例,都是已经变化过的实例。
@Component,@directive,@Pipe都是Injectable的子型,如果都没有,则需要Injectable()装饰器。
import {Injectable} from '@angular/core'
@Injectable()
export class Logger(){
logs:string[] = []
log(message:string){
this.logs.push(message)
console.log(message)
}
}
依赖注入是angular中的重要技巧,必须使用纯熟。