依赖注入是angular中一个十分常用的功能,但由于自己以前写的代码并没有用到依赖注入的高级功能,所以也就没有系统的学习过,正好这段时间看angular的官方文档看到了这里,就简单的总结一下。
什么是依赖注入
关于什么是依赖注入,实际上还是很好理解的,依赖注入通常和控制反转联系在一起
依赖注入(DI)和控制反转(IOC)基本是一个意思,因为说起来谁都离不开谁。
简单来说,类A依赖类B,但A不控制B的创建和销毁,仅使用B,那么B的控制权则交给A之外处理,这叫控制反转(IOC)。
由于A依赖于B,因此在A中必然要使用B的instance,我们可以通过A的构造函数将B的实例注入,比如:
下面是一个简单的,用ts实现的依赖注入的例子:
class B { }
class A {
constructor(b: B) {
console.log(b);
}
}
const b = new B();
// 将B的实例注入到a中
const a = new A(b);
angular的依赖注入
angular 有自己的 DI 框架,所以在实现依赖注入的过程被隐藏了,我们只需要很简单的步骤就可以使用其强大的依赖注入功能。
angular的依赖注入可以分为三个步骤:
- 得到依赖项
- 查找依赖项所对应的对象
- 执行时注入
下面是一个例子
使用依赖注入组件
@Component({
selector: 'app-test',
template: ``
})
export class TestComponent {
constructor(userService: UserService) {
}
}
创建将被注入的UserService
// @Injectable() 装饰器把它标记为可供注入的服务
@Injectable({
// 指定把被装饰类的提供商放到 root 注入器中,也就是一个全局的对象
providedIn: 'root',
})
export class UserService {
constructor() { }
}
这样就算把一个UserService注入到了TestComponent中,并且因为提供商被放到了 root 注入器中,因此你可以在整个应用中使用该对象——
在某个注入器的范围内,服务是单例的。也就是说,在指定的注入器中最多只有某个服务的最多一个实例
三种提供商
angular一共有三种提供商,@Injectable,@NgModule,@Component
@Injectable
@Injectable的提供方式就是上面所提到的那样。
@Injectable() 装饰器会标出每个服务类。服务类的元数据选项 providedIn 会指定一个注入器(通常为 root 来用被装饰的类作为该服务的提供商。 当可注入的类向 root 注入器提供了自己的服务时,任何导入了该类的地方都能使用这个服务。同理,你可以向某个特定 NgModule 的注入器提供自己的服务。
这种注入方式也是使用angular-cli生成服务时默认的方式,也是最常用的方式,它同另外两种注入方式相比,有一个显著的优点:如果 NgModule 没有用到该服务,那么这个服务就会被摇树优化掉。
什么是摇树优化呢?
摇树优化是指一个编译器选项,意思是把应用中未引用过的代码从最终生成的包中移除。 如果提供商是可摇树优化的,Angular 编译器就会从最终的输出内容中移除应用代码中从未用过的服务。 这会显著减小你的打包体积。
@NgModule
你还可以在非根 NgModule 元数据的 providedIn 选项中配置一个模块级的提供商,以便把该服务的范围限定到该模块一级。
一般来说,你不必在 providedIn 中指定 AppModule,因为应用中的 root 注入器就是 AppModule 注入器。 不过,如果你在 AppModule 的 @NgModule() 元数据中配置了全应用级的提供商,它就会覆盖通过 @Injectable() 配置的那一个。 你可以用这种方式来为那些供多个应用使用的服务指定非默认的提供商。
使用方式
providers: [
{ provide: LocationStrategy }
]
@Component
NgModule 中每个组件都有它自己的注入器。 通过使用 @Component 元数据在组件级配置某个提供商,你可以把这个提供商的范围限定到该组件及其子组件。
使用方式如下:
@Component({
selector: 'app-test',
providers: [ UserService ],
template: ``
})
export class TestComponent {
constructor(userService: UserService) {
}
}
以上就是三种提供依赖注入的方式。
总结
angular的依赖注入基本用法就基本像上面说的那样了,而高级用法,比如@Optional等装饰器,由于自己到现在为止都没用过,就不在献丑,留待以后,拥有了更丰富的开发经验,再来尝试。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。