浅析angular2依赖注入


依赖注入介绍

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

简而言之, 没事你不要来找我,有事我会去找你。

Angular依赖注入

首先介绍几个简单的概念。

1.注入器(Inject):就像制造工厂,提供了一些列的接口用于创建依赖对象的实例

2.Provider:用于配置注入器,注入器通过它来创建被依赖对象的实例,Provider把标识映射到工厂方法中,被依赖的对象就是通过该方法创建的。

3.依赖(Dependence):指定了被依赖对象的类型,注入器会根据此类型创建对应的对象。

在组件中注入服务

Angular在底层做了大量的初始化工作,这大大简化了创建依赖注入的过程,在组件中使用依赖注入需要完成以下三个步骤

-通过import导入被依赖对象的服务

-在组建中配置注入器。在启动组件时,Angular会读取@Component装饰器里的providers元数据,它是一个数组,配置了该组件需要使用到的所有依赖,Angular的依赖注入框架就会根据这个列表去创建对应对象的实例。

-在组件构造函数中声明所注入的依赖。注入器就会根据构造函数上的声明,在组件初始化时通过第二步中的providers元数据配置依赖,为构造函数提供对应的依赖服务,最终完成注入过程。



在服务中注入服务

除了组件服务依赖,服务间的相互调用也很常见。

//logger.service.ts


//contact.service.ts

//在组件的providers元数据中注册服务

providers:[LoggerService,ContactService]

在上述中,LoggerService和ContactService这两个服务都用了@Injectable()装饰器,实际上它并不是必须的,只有一个服务依赖其他服务时,才需要用@Injectable()显示装饰。上述的LoggerService服务并没有依赖其他服务,它可以不用@Injectable()装饰,而ContactService服务依赖了其他服务,则需要@Injectable()装饰。


Angular官方推荐无论是否有依赖其他服务,都应该使用@Injectable()来撞死服务。一方面,开发者在给某个组件注入其他服务时,无需再确认该服务是否添加了@Injectable();另一方面,这也是一种良好的团队协作方式,整个团队遵循相同的开发原则。

在模块中注入服务

在根组件中注入这个服务,所有子组件都能共享这个服务。

在模块中注入服务和之前的注入场景稍有不同。Angular在启动程序时会启动一个根模块,并加载它所依赖的其他模块,此时会生成一个全局的根注入器,由该注入器创建的依赖注入对象在整个应用程序级别可见,并共享一个实例。同时根模块会指定一个根组件并启动,由该根组件添加的依赖注入对象是组件树级别可见,在根组件以及子组件中共享一个实例。


层级注入

Angular以组件为基础,项目开发中自然会有层级嵌套的情况,这种组织关系组成了组件树。根组件下面的各层级的子组件,可以出现在任何层级的任何组件中,每个组件可以拥有一个或多个依赖对象的注入,每个依赖对象对于注入器而言都是单例。


//生成唯一标识服务


//子组件A


//子组件B


//父组件


结果将输出:

Contact-List

ContactA:0.4500488165839276

ContactB:0.5389674473022938


每个子组件都创建了自己独立的注入器,也就是说通过依赖注入的Random服务都是独立的,如果把注入器提升到父组件中,则结果将会不一样。



此时,结果变为

Contact-List

ContactA:0.6257492668005642

ContactB:0.6257492668005642

上述的输出结果说明了子组件继承了父组件的注入器,所以子组件使用了相同的Random实例,输出了相同的结果。

那么,该如何选择在根组件还是在子组件中注入服务呢?

这取决于想让注入的依赖服务具有局部性还是全局性,由于每个注入器总是将它提供的服务维持单例,因此,如果不需要针对每个组件都提供独立的服务单例,就可以在根组件中注入,整个组件树共享根注入器提供的服务实例;如果需要针对每个组件提供不同的服务实例,就应该在格子组件中配置providers元数据来注入服务。

Angular如何查找到合适的服务实例呢?

在组件的构造函数视图注入某个服务的时候,Angular会先从当前组件的注入器中查找,找不到就继续往父组件的注入器查找,直到根组件注入器,最后到应用根注入器,此时找不到的话就会报错。

你可能感兴趣的:(浅析angular2依赖注入)