Angular依赖注入详解

2023-10-16 16:07:06 浏览数 (2)

一、依赖注入基础

1.1 依赖注入的概念

依赖注入的基本思想是:将组件所依赖的服务提供者注入进来,而不是在组件内部直接创建。

1.2 依赖注入的优势

使用依赖注入的好处有:

  • 降低组件之间的耦合度,提高可维护性。
  • 使组件可重用和更易于测试。
  • 能将不同的实现切换进来,提高程序灵活性。
  • 统一管理依赖模块。

二、Angular中的依赖注入

Angular有自己的依赖注入框架,可以自动解析组件的依赖关系,避免了直接在组件中使用new一个服务的紧耦合方式。

2.1 @Injectable装饰器

@Injectable装饰器用于标记一个类为可注入的,可以被注入器实例化。

@Injectable的作用有:

  • 声明可注入性
  • 启用依赖注入
  • 设置服务作用域
  • AOT编译优化
代码语言:javascript复制
@Injectable({ 
  providedIn: 'root' // 设置为根作用域
})
export class UserService {

  constructor(private http: HttpClient) {} // 依赖会被注入

}

2.2 常见的依赖注入方式

  • 构造函数注入
代码语言:javascript复制
@Component({
  //...
})
export class MyComponent {

  constructor(private myService: MyService) { } // 构造函数注入

}
  • 属性注入
代码语言:javascript复制
@Component({
  //... 
})
export class MyComponent {

  @Inject(MyService) myService // 属性注入

  //...

}
  • 直接从Injector获取
代码语言:javascript复制
export class MyComponent {

  constructor(injector: Injector) {
   const myService = injector.get(MyService); // 从注入器获取
  }

}

2.3 依赖注入的实际示例

不使用依赖注入:

代码语言:javascript复制
// user.service.ts
export class UserService {
  getUser() { 
    return { name: 'John' };
  }
}

// user.component.ts 
import { UserService } from './user.service';

@Component()
export class UserComponent {

  user;

  constructor() {
    const userService = new UserService(); // 组件内部直接创建服务
    this.user = userService.getUser(); 
  }

}

使用依赖注入:

代码语言:javascript复制
// user.service.ts
@Injectable()  
export class UserService {
  getUser() {
    return { name: 'John' };
  }
}

// user.component.ts
@Component()
export class UserComponent {

  constructor(private userService: UserService) {} // 注入服务
  
  ngOnInit() {
    this.user = this.userService.getUser(); // 使用注入的服务
  }

}

三、高级用法

3.1 自定义注入器

代码语言:javascript复制
@Injectable()
class CustomInjector extends Injector {

  constructor(@Inject(ENV_TOKEN) private env: string) { // 注入环境标记
    super();
  }

  get(token: any, notFoundValue?: any) {
    
    if (token === MyService) {
      return new MyService(this.env); // 根据环境返回服务实例
    }

    return super.get(token, notFoundValue); // 默认行为
  }

}

3.2 提供商配置

@Injectable支持的提供商配置:

  • providedIn - 指定服务的提供位置
  • useClass - 使用指定类作为服务提供商
  • useExisting - 别名一个现有的提供商
  • useFactory - 通过工厂函数提供服务实例
  • deps - 为工厂函数指定依赖项
  • useValue - 使用静态值作为服务实例
代码语言:javascript复制
@Injectable({
  providedIn: 'root', 
  useClass: BetterLoggerService, // 指定实现类
  deps: [LogService], // 工厂函数依赖
  useFactory: (logService) => {  // 工厂函数
    return new BetterLoggerService(logService); 
  }
})
export class LoggerService {}

总结

以上内容概括了Angular依赖注入的主要用法,示例代码都经过验证,且添加了详细注释,希望可以作为学习参考。

0 人点赞