SAP Spartacus 中的依赖注入 Dependency Injection 介绍

简介: SAP Spartacus 中的依赖注入 Dependency Injection 介绍

先了解 Angular 中的依赖注入


依赖项是指某个类执行其功能所需的服务或对象。依赖项注入(DI)是一种设计模式,在这种设计模式中,类会从外部源请求依赖项而不是让类自己来创建它们。

Angular 的 DI 框架会在实例化某个类时为其提供依赖。你可以使用 Angular DI 来提高应用程序的灵活性和模块化程度。


如何创建一个新的可以被注入的 service ?

命令行:ng generate service heroes/hero


自动生成的代码,注意注解 @Injectable:


import { Injectable } from '@angular/core';


@Injectable({

 providedIn: 'root',

})

export class HeroService {

 constructor() { }

}

1

2

3

4

5

6

7

8

@Injectable() 装饰器会指定 Angular 可以在 DI 体系中使用此类。元数据 providedIn: ‘root’ 表示 HeroService 在整个应用程序中都是可见的。


配置提供者

通过配置提供者,你可以把服务提供给那些需要它们的应用部件。


依赖提供者会使用 DI 令牌来配置注入器,注入器会用它来提供这个依赖值的具体的、运行时版本。


如果你把服务类指定为提供者令牌,那么注入器的默认行为是用 new 来实例化那个类。


在下面这个例子中,Logger 类提供了 Logger 的实例。


providers: [Logger]

1

当使用提供者配置注入器时,会将该提供者与依赖项注入令牌(或叫 DI 令牌)关联起来。注入器允许 Angular 创建任何内部依赖项的映射。DI 令牌会充当该映射的键名。


当你使用 HeroService 类的类型来定义构造函数参数时,Angular 会注入与这个 HeroService 类令牌相关联的服务:


constructor(heroService: HeroService)

1

这里构造函数参数 heroService 实际上是一个令牌。


这个配置:


providers: [Logger]

1

实际上是下面写法的简写:


[{ provide: Logger, useClass: Logger }]

1

provide 属性存有令牌,它作为一个 key,在定位依赖值和配置注入器时使用。

第二个属性是一个提供者定义对象,它告诉注入器要如何创建依赖值。 提供者定义对象中的 key 可以是 useClass —— 就像这个例子中一样。 也可以是 useExisting、useValue 或 useFactory。 每一个 key 都用于提供一种不同类型的依赖。

不同的类可以提供相同的服务。例如,以下代码告诉注入器,当组件使用 Logger 令牌请求一个 logger 时,给它返回一个 BetterLogger.


这样,当我们的应用程序,在 constructor 里使用下面代码试图注入 Logger 时:


constructor(logger: Logger)

1

运行时我们拿到的就是 BetterLogger 实例。


injection token 的使用方法

使用 TypeScript interface 定义一个 AppConfig 类型(略)


基于 AppConfig 类型创建一个常量:


export const HERO_DI_CONFIG: AppConfig = {

 apiEndpoint: 'api.heroes.com',

 title: 'Dependency Injection'

};

1

2

3

4

要提供并注入配置对象,请在 @NgModule() 的 providers 数组中指定该对象。

providers: [

{ provide: APP_CONFIG, useValue: HERO_DI_CONFIG }

],

1

2

3

上面代码里 provide 属性 APP_CONFIG 就是一个令牌,我们还需要使用代码创建这个令牌。


import { InjectionToken } from '@angular/core';


export const APP_CONFIG = new InjectionToken('app.config');

1

2

3

其中AppConfig 通过类型参数传入令牌构造函数里。app.config 是令牌描述信息。


最后一步,在应用程序的构造函数里,用 @Inject,注入这个令牌。运行时,config 的值即为令牌关联的常量:HERO_DI_CONFIG

constructor(@Inject(APP_CONFIG) config: AppConfig) {

 this.title = config.title;

}

1

2

3

为什么我们不能直接把第一步用 interface 创建的 AppConfig 作为 provide 的值,而要大费周章,创建一个 InjectionToken 呢?


虽然 TypeScript 的 AppConfig 接口可以在类中提供类型支持,但它在依赖注入时却没有任何作用。在 TypeScript 中,接口是一项设计期工件,它没有可供 DI 框架使用的运行时表示形式或令牌。

当转译器把 TypeScript 转换成 JavaScript 时,接口就会消失,因为 JavaScript 没有接口。

由于 Angular 在运行期没有接口,所以该接口不能作为令牌,也不能注入它。


因此下列代码不能工作:


// Can't use interface as provider token

[{ provide: AppConfig, useValue: HERO_DI_CONFIG })]

1

2

看一个 SAP Spartacus 中 Injection Token 的使用例子:

image.pngimage.pngimage.png最后在 PageLayoutService 里使用到了这个令牌指向的服务实例:PageLayoutHandler 组成的数组。

image.png

目录
相关文章
|
缓存 负载均衡 前端开发
SAP Spartacus 和 Sticky session 相关的话题
SAP Spartacus 和 Sticky session 相关的话题
SAP Emarsys 和 SAP Spartacus 的集成
SAP Emarsys 和 SAP Spartacus 的集成
|
API 开发者
Google Tag Manager (GTM) 和 Adobe AEPL 在 SAP Spartacus 中的应用
Google Tag Manager (GTM) 和 Adobe AEPL 在 SAP Spartacus 中的应用
|
6月前
|
存储 缓存 前端开发
关于 SAP Spartacus Optimization Engine 里的 cache 参数使用注意事项
关于 SAP Spartacus Optimization Engine 里的 cache 参数使用注意事项
|
6月前
|
JSON 开发者 数据格式
关于 SAP Spartacus LandingPage2Template 区域的 layout 设计实现
关于 SAP Spartacus LandingPage2Template 区域的 layout 设计实现
|
6月前
|
搜索推荐 开发者 UED
关于 SAP Spartacus 层的 UI 设计
关于 SAP Spartacus 层的 UI 设计
|
6月前
|
开发者 UED
SAP Spartacus BREAKPOINT 枚举类型在 Spartacus layout 实现中的作用
SAP Spartacus BREAKPOINT 枚举类型在 Spartacus layout 实现中的作用
|
JavaScript 容器
关于 SAP Spartacus generic-link component 的模板代码
关于 SAP Spartacus generic-link component 的模板代码
|
前端开发 搜索推荐 JavaScript
什么是 SAP Spartacus 的 CMS Page Connector
什么是 SAP Spartacus 的 CMS Page Connector
|
前端开发 JavaScript API
SAP Commerce Accelerator Storefront 到 Spartacus 的 page by page migration 策略
SAP Commerce Accelerator Storefront 到 Spartacus 的 page by page migration 策略