2018年继续来搞Angular!

什么是依赖注入?

根据维基百科,依赖注入(Dependency Injection)是种解决项目依赖性的设计模式, 好处有大致以下几点:

Angular中的DI

Angular的依赖注入有三个重要概念:

注入器连接了调用方和提供方,使得开发人员很轻松的实现依赖注入。(注:Angular框架已经实现了注入器的生成和调用,并不需要开发者去实现)

注入服务

  1. 通过import导入被依赖对象的服务
  2. Angular读取 @Component@Injectable@Module 装饰器里providers元数据
  3. 在组件构造函数中声明

这样几步,此组件及其子组件都能共享根组件创建的实例,如果子组件或模块不想复用从根组件获取的服务,可以在自己的注入器中重新配置注入(层级注入)。

需要注意的是:

Provider

Provider这种设计模式由来已久,在前后台各种技术领域中被广泛使用。它藐视了注入器如何初始化Token所对应的依赖服务,最终注入到组件或者其他服务中。

Provider注册方式

对于调用者来说,业务代码和接口没有改变,从而带来极大的便利

{provider: Render, useClass: DomRender} //DOM渲染方式
//{provider: Render, useClass: CanvasRender} //Canvas渲染方式
//{provider: Render, useClass: ServerRender} //服务端渲染方式

实际项目中,以来的对象不一定是类

{provider: 'name', useValue: 'William Jing'}

实现多个依赖,一个对象实例的所用,例如为了让新旧服务同时可用,新服务兼容老服务,可以使用此种注册方式

{provider: NewService, useClass: NewService}
{provider: OldService, useExisting: NewService}

有时候依赖对象是动态变化的,可能需要环境、执行权限来生成,工厂Provider可以提供解决这个问题,通过暴露一个工厂方法,返回一个最终的依赖对象

let contactServiceFactory = (_logger: LoggerService, _userService: UserService) =>{
  return new contactService(_logger, _userService.user.isAuthorized)
}
export let contactServiceProvider = {
  provider: ContactService,
  userFactory: contactServiceFactory,
  deps: [LoggerService, UserService]
};