面试题答案
一键面试Angular依赖注入基本原理
- 控制反转(IoC)概念:依赖注入是控制反转(IoC)的一种实现方式。在传统编程中,对象通常会自己创建其依赖对象,即对象控制依赖对象的创建和生命周期。而在依赖注入中,控制权被反转,由外部容器(在Angular中是注入器)负责创建和管理依赖对象,并将它们注入到需要的对象中。
- 注入器(Injector):Angular使用注入器来管理依赖的创建、查找和注入。注入器维护一个依赖提供者(Provider)的注册表,当一个组件或服务需要某个依赖时,注入器会根据注册表查找对应的提供者来创建或返回该依赖实例。
- 依赖提供者(Provider):提供者是一种告诉注入器如何创建或获取依赖对象的机制。常见的提供者类型包括
ClassProvider
(用于创建类的实例)、ValueProvider
(用于提供一个值)、FactoryProvider
(通过工厂函数创建对象)等。
实际项目开发中常使用依赖注入的场景
- 服务复用:多个组件可能需要使用同一个服务,通过依赖注入,注入器可以创建该服务的单例实例并注入到各个组件中,避免重复创建。例如,在一个电商应用中,购物车服务可能被商品详情组件、结算组件等多个组件使用。
- 测试隔离:在单元测试中,通过依赖注入可以很方便地替换真实的依赖为模拟对象,从而隔离被测试组件与外部依赖,使测试更加独立和可控。比如,测试一个用户登录组件时,可以注入一个模拟的认证服务,而不是真实的认证服务。
- 模块间解耦:不同模块之间可能存在依赖关系,依赖注入可以将这种依赖关系解耦。例如,一个功能模块可能依赖于一个日志记录服务,通过依赖注入,该功能模块不需要知道日志记录服务具体如何实现,只需要声明依赖即可。
在Angular服务中使用依赖注入示例
假设我们有一个LoggerService
用于记录日志,另一个UserService
需要使用LoggerService
来记录用户相关操作。
- 创建
LoggerService
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class LoggerService {
log(message: string) {
console.log(`[LOG] ${message}`);
}
}
这里@Injectable({ providedIn: 'root' })
表示该服务在根注入器中提供,是一个单例服务。
- 创建
UserService
并注入LoggerService
:
import { Injectable } from '@angular/core';
import { LoggerService } from './logger.service';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private logger: LoggerService) {}
registerUser(username: string) {
this.logger.log(`User ${username} registered`);
// 实际注册用户逻辑
}
}
在UserService
的构造函数中,通过参数private logger: LoggerService
声明了对LoggerService
的依赖,Angular注入器会自动创建LoggerService
的实例并注入到UserService
中。这样UserService
就可以使用LoggerService
的log
方法来记录用户注册相关的日志。