依赖注入(DI)是一种重要的应用设计模式。 DI 是一种编码模式,其中的类会从外部源中请求获取依赖,而不是自己创建它们。
了解DI机制,首先要了解Provider的概念。
provider是什么?
provider是提供商,他们提供什么?提供服务。所以,provider可以create or deliver service。而服务呢,需要有一个提供商。
提供商 (provider)
一个实现了 Provider 接口的对象。一个提供商对象定义了如何获取与 DI 令牌(token) 相关联的可注入依赖。 注入器会使用这个提供商来创建它所依赖的那些类的实例。
Angular 会为其自带的服务在每个注入器中注册它自己的提供商。你也可以自己注册应用所需的自己的服务提供商。
具体的服务是一个类 ,是加上了@injectable()装饰器的类。 它被标记为可注入的服务。你必须先使用provider 提供一个依赖注入器(dependency injector)的配置,否则angular无法将它注入到任何地方。
默认情况下,该服务的装饰器是用
@injectable({providedIn: 'root'}
)
属性进行配置的,它会为该服务创建一个提供商。root表示该服务的提供商是根注入器。
如何提供服务呢?
provider就像一个说明书,来告知inject如何创建服务。
@NgMoudle() 和@Component()
装饰器都有用一个 providers 元数据选项,在那里你可以配置 NgModule 级或组件级的注入器。
如果某个组件需要用到这个服务,那么不需要自己去创建服务的实例,只需要在构造方法里面添加这个服务的声明就可以了。
服务是作为单例存在于注入器中的,在指定的注入器中,只有一个服务实例。
当组件或服务声明某个依赖项时,该类的构造函数会以参数的形式接收那个依赖项。 通过给这个参数加上 @Optional() 注解,你可以告诉 Angular,该依赖是可选的。
注入器 (injector)
Angular 依赖注入系统中可以在缓存中根据名字查找依赖,也可以通过配置过的提供商来创建依赖。 启动过程中会自动为每个模块创建一个注入器,并被组件树继承。
注入器会提供依赖的一个单例,并把这个单例对象注入到多个组件中。
模块和组件级别的注入器树可以为它们拥有的组件及其子组件提供同一个依赖的不同实例。
你可以为同一个依赖使用不同的提供商来配置这些注入器,这些提供商可以为依赖提供不同的实现。
简单流程:
injector 通过 provider 来创建 service 的 instance。
服务注册的层级:
- root:所有组件共享一个实例。
- @NgMoudle providers:该服务的同一个实例被该module下的所有组件使用。
- @component providers:每个组件创建一个该服务的实例。
网友评论