是什么
依赖注入(dependency injection,DI)是这样一个系统,它让程序中的某部分可以访问其他部分,而且我们可以配置它们的访问方式。
简单来说,就是new好了依赖的对象注入进去,而不是在类中显式的new一个依赖的对象。依赖注入的可以是继承依赖类(即constructor参数)的任何类
基于控制反转(Ioc)的设计原则,减弱耦合性
怎么用
即如何给组件注入服务:
创建该服务的类,服务类上面这个@Injectable()装饰器
-
配置要注入的依赖,即提供者
Angular 在启动过程中自动为我们创建一个应用级注入器,即隐式注入器。我们必须通过注册provider来配置注入器,这些provider为应用创建所需服务。
或者在 NgModule 中注册provider,或者在应用组件中。使用Provider:[1]
告诉Angular如何*根据指定的令牌创建对象***1的内容见下部分- NgModule 中的provider是被注册到根注入器。这意味着在 NgModule 中注册的provider可以被整个应用访问。
- 在应用组件中注册的provider只在该组件及其子组件中可用。
在准备接收注入的部件上声明该依赖
先导入该服务(import),然后在组件的构造函数中声明它。声明有两种方式:使用Inject注解的和不使用Inject注解的
非 Type 类型的参数只能用 @Inject(Something) 的方式注入;Type 类型的参数两种方式都可以,比如
//非Type类型
constructor(@Inject(ApiService) private apiService){ }
//Type类型
constructor(private http: Http) { } //推荐
constructor(@Inject(Http) private http) { }
constructor(@Inject(Http) private http: Http) { }
因为 Type 类型的对象,会被 TypeScript 编译器编译。即我们通过 class 关键字声明的服务,最终都会编译成 ES5 的函数对象
显示注入器
可以写使用显式注入器的代码,但却很少这样做
injector = ReflectiveInjector.resolveAndCreate([Car, Engine, Tires]);
let car = injector.get(Car);
provider配置
单例模式:服务的构造函数无参数,每次注入时返回同一个实例,1的内容:
{provide:'令牌名',useClass:注入服务的类名}
可简写为:注入服务的类名
工厂模式:调用构造函数时需要提供参数
{provide: '令牌名',useFactory:函数}
值模式:当需要一个常量,而它会根据应用的其他部分甚至环境进行重定义时,这种方式非常有用
{provide: '令牌名', useValue: 'someValue'}
别名模式
{provide: '令牌名', useValue: '其他令牌名'}
四种接口的API如下:
export interface ClassProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
useClass: Type<any>;
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}
export interface FactoryProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
// 设置用于创建对象的工厂函数
useFactory: Function;
// 依赖对象列表
deps?: any[];
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}
export interface ValueProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
// 设置注入的对象
useValue: any;
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}
export interface ExistingProvider {
// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串
provide: any;
// 设置注入的对象
useExisting: any;
// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表
multi?: boolean;
}