第四章 依赖注入 ng g service ...
生成到文件夹里的写法 ng g service/product
依赖注入、控制反转
依赖注入的好处
1、可重用性
@NgModule({
在angular中指定providers声明那些对象需要依赖注入,而providers是一个数组,每一个元素是一个provide
providers: [ProductService]
上面的代码等价于下面的代码 token代表的是一个对象可被注入的类型 token由配置对象providers的对应provide属性来决定
下面代码的意思:注册一个类型是productService的token,当有组件或指令声明自己需要一个类型为productService的token时,实例化一个productService并将其注入到目标对象
providers: [{provide:ProductService, useClass:ProductService}]
})
export class AppModule {}
@Component ({
...省略组件配置
})
组件或者指令声明自己需要类型为productService的token 要使用其构造函数
ProductComponent这个组件本身并不知道传进来的是productService的哪个实现,更不需要实例化这个ProductService
只需要使用angular为它创建好的对象,调用其方法就可以,如果需要在其他组件中重用这个 ProductComponent组件,而其组件又实现了一个productService的类,可以修改那个组件的AppModule声明成providers: [{provide:ProductService, useClass:AnotherProductService}],这时angular框架将会实现AnotherProductService这个类型,并将其注入到ProductComponent中,而ProductComponent本身并不需要什么更改
export class ProductComponent {
product: Product;
声明需要一个productService的token,angular框架看见这个声明后,会去providers里面找对应的类是什么,这里面写的是productService的类,会实例化一个ProductService,将实例注入到构造函数内
constructor(productService: ProductService){
this.product = productService.getProduct();
}
}
2、可测性
LoginComponent 可创建登陆功能组件
MockLoginService
RealLoginService
注入器:负责注入组件需要的对象,注入器是angular提供的一个服务类,一般情况下不需要直接调用注入器的方法,注入器会自动通过组件的构造函数将组件所需的对象注入到组件
一个构造函数声明了一个productService属性,在这个属性上我们声明它的类型是ProductService
constructor(private productService:ProductService){...}
当注入器看见这样一个声明的时候,就会在angular应用中寻找一个ProductService的实例,如果能找到这个实例,就会把实例注入到productService这个对象中,直接使用就可以了
提供器:providers
一般情况下我们会通过组件或者模块的providers属性,来声明provider
providers:[ProductService] 等同于providers: [{provide:ProductService, useClass:ProductService}]
通过一个工厂方法返回一个实例
providers: [{provide:ProductService, useFactory:() =>{...}}]
提供器的作用域规则
1.当一个提供器声明在一个app模块当中时,他是对所有组件可见的,所有组件都可以注入
2.当一个提供器声明在一个组件中时,它只对声明它的组件及其子组件注入,其他组件不可以注入
3.当声明在组件中的提供器和声明在app模块中的提供器具有相同的token时,声明在组将中的提供器会覆盖模块中的提供器
4.一般情况下我们应该把提供器优先声明在模块中,只有服务必须某个组件之外的其他组件不可见时,才把提供器声明在组件中,
使用工厂和值声明提供器