Механизм внедрения зависимостей на клиенте
В данном разделе рассмотрены особенности передачи клиентских сервисов с использованием механизма внедрения зависимостей.
У сервиса имеется имя и интерфейс. Например, сервис для получения информации о текущей карточке имеет имя $CardInfo
, и интерфейс GenModels.CardInfoModel
. Получить сервис можно по имени при помощи метода getService
у объекта элемента управления, разметки или глобального объекта app
. Например, таким образом можно получить сервис $CardInfo
в обработчике события:
export function onCustomButtonClick(sender: CustomButton, args: IEventArgs) {
const cardInfo = sender.getService($CardInfo);
}
Сервисы, как правило, размещаются в контейнерах — специальных объектах. Имя сервиса — это ключ, по которому данный сервис можно получить в сервис-контейнере. Получить сервис-контейнер можно вызвав getService
без параметров. Так альтернативный способ получения сервиса по ключу из контейнера будет выглядеть так:
export function onCustomButtonClick(sender: CustomButton, args: IEventArgs) {
const cardInfo = sender.getService()[$CardInfo] as GenModels.CardInfoModel; (1)
const cardInfo2 = sender.getService<$CardInfo>().cardInfo; (2)
}
1 | Получаем либо по ключу |
2 | Либо иным образом |
Сервис-контейнер уровня приложения доступен через глобальный объект app, однако его не рекомендуется использовать в большинстве случаев.
Сервис контейнер в элементах управления также доступен через параметр services
(он же props
при отрисовке элемента управления как React-компонента).
Все стандартные сервисы Web-клиента (приведены в JSDoc API).
Создание сервисов
-
Описание интерфейса сервиса и его имени.
-
Определение реализации.
-
Регистрация реализации.
-
Первое, что нужно сделать — выбрать название сервиса. Допустим, наш сервис будет называться
Greeting
. Тогда описание интерфейса и имени сервиса будет выглядеть следующим образом:export interface IGreetingService { showGreeting(name: string): Promise<void>; } export type $Greeting = { greeting: IGreetingService }; export const $Greeting = serviceName<$Greeting, IGreetingService>(x => greeting);
-
Реализацию сервиса рекомендуется определять в отдельном от интерфейса файле (чтобы не создавать лишние зависимости). Реализацией будет определение класса, реализующего интерфейс
IGreetingService
.export class GreetingSevice implements IGreetingService { constructor(private services: $MessageWindow) { } showGreeting(name: string): Promise<void>{ return this.services.messageWindow.showInfo("Добро пожаловать, " + name); } }
-
Регистрируются сервисы в файле
Index.ts
веб-расширения через вызовregisterExtension
. Если сервис имеет отношение к разметке, то следует передавать его в полеlayoutServices
, иначе вglobalServices
.extensionManager.registerExtension({ name: "Greeting", version: "1.0", layoutServices: [ Service.fromFactory($Greeting, (services: $StandardServices & $StandardControllers) => new GreetingSevice(services)) ] })
-