Angular服务依赖注入基本原理
- 容器管理:Angular维护一个依赖注入容器,这个容器是一个对象,用于存储各种依赖(即服务)的实例。当组件或其他服务需要某个依赖时,会向这个容器请求。
- 注册机制:在应用模块(
NgModule
)中,通过providers
数组将服务注册到依赖注入容器。注册时,可以指定服务的提供商(provider),提供商可以是类本身,也可以是一个工厂函数等。例如,providers: [MyService]
就将MyService
类注册为一个可注入的服务。
- 解析与实例化:当组件或其他服务需要注入某个依赖时,Angular依赖注入系统会在容器中查找该依赖。如果容器中不存在该依赖的实例,它会根据注册的提供商信息创建一个新的实例。例如,如果是基于类的提供商,就会使用
new
关键字创建一个新的类实例。然后,将这个实例注入到需要它的组件或服务中。
实际项目中使用依赖注入的常见场景
- 数据服务
- 场景描述:在一个电商应用中,可能有一个
ProductService
用于从后端获取产品数据。多个组件,如产品列表组件、产品详情组件等都需要获取产品数据。通过依赖注入,将ProductService
注入到这些组件中,使得组件无需自己创建ProductService
的实例,降低了组件与数据获取逻辑的耦合度。
- 代码示例:
// product.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private http: HttpClient) {}
getProducts() {
return this.http.get('/api/products');
}
}
// product - list.component.ts
import { Component, OnInit } from '@angular/core';
import { ProductService } from './product.service';
@Component({
selector: 'app - product - list',
templateUrl: './product - list.component.html'
})
export class ProductListComponent implements OnInit {
products: any[];
constructor(private productService: ProductService) {}
ngOnInit() {
this.productService.getProducts().subscribe(data => {
this.products = data;
});
}
}
- 日志服务
- 场景描述:在一个大型企业级应用中,不同的组件和服务在运行过程中可能需要记录日志。创建一个
LoggerService
,通过依赖注入将其注入到需要记录日志的组件或服务中。这样,日志记录的逻辑可以集中管理,并且方便在不同环境(开发、生产等)中切换日志记录策略。
- 代码示例:
// logger.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class LoggerService {
log(message: string) {
console.log(`[LOG] ${message}`);
}
}
// user - auth.service.ts
import { Injectable } from '@angular/core';
import { LoggerService } from './logger.service';
@Injectable({
providedIn: 'root'
})
export class UserAuthService {
constructor(private logger: LoggerService) {}
login(username: string, password: string) {
this.logger.log(`Trying to login user: ${username}`);
// 实际登录逻辑
}
}