Dependency Injection¶
Начиная с версии TESSA 4.0 в web-клиенте используется внедрение зависимостей. DI построен на базе библиотеки InversifyJS.
Внедрение зависимостей¶
Для получения какой-либо зависимости нужно указать токен этого типа. Токен выглядит как Название типа зависимости
+ $
. Например для ICardService
токен будет ICardService$
. Зависимости внедряются следующим образом:
@extension()
export class MyCardUIExtension extends CardUIExtension {
constructor(@inject(ICardService$) private _cardService: ICardService) {}
}
Дополнительно через декоратор inject
можно указывать опциональные, именновые зависимости.
Создание внедряемых типов¶
Для того чтобы создать тип, который можно будет использовать через DI, необходимо:
- Описать интерфейс типа
export interface IMySolutionType {}
- Описать имплементацию и указать декоратор
injectable
:@injectable() export class MySolutionType implements IMySolutionType { constructor(@inject(ICardService$) private _cardService: ICardService) {} // для примера укажем зависимость }
- Создать токен типа зависимости:
export const IMySolutionType$ = createInjectToken<IMySolutionType>('IMySolutionType');
- В регистраторе зарегистрировать тип в DI контейнере:
// registrator.ts export const SolutionRegistrator: ExtensionRegistrator = { async registerTypes(container) { container.bind(IMySolutionType$).to(MySolutionType); }, async registerExtensions() {} };
Теперь можно использовать новый тип, как любую другую зависимость:
@extension()
export class MyCardUIExtension extends CardUIExtension {
constructor(@inject(IMySolutionType$) private _myDep: IMySolutionType) {}
}
Переопределение зависимостей¶
С помощью DI можно подменять зависимости для различных объектов в системе. Например можно сделать свою реализацию HttpClient
и внедрить её только в сервис карточек:
@injectable()
export class MyApiClient extends ApiClient {
protected override async getDefaultOptions(): Promise<ApiClientOptions> {
const options = await super.getDefaultOptions();
options.timeout = 5000; // для примера ставим таймаут
return options;
}
}
// registrator.ts
export const SolutionRegistrator: ExtensionRegistrator = {
async registerTypes(container) {
container.bind(IApiClient$).to(MyApiClient).whenInjectedInto(ICardService$);
},
async registerExtensions() {}
};
Теперь для всех вызовов сервиса карточек будет использоваться реализация MyApiClient
.