Перейти к содержанию

Dependency Injection

Начиная с версии TESSA 4.0 в web-клиенте используется внедрение зависимостей. DI построен на базе библиотеки InversifyJS.

Внедрение зависимостей

Для получения какой-либо зависимости нужно указать токен этого типа. Токен выглядит как Название типа зависимости + $. Например для ICardService токен будет ICardService$. Зависимости внедряются следующим образом:

@extension() export class MyCardUIExtension extends CardUIExtension { constructor(@inject(ICardService$) private _cardService: ICardService) {} }

Дополнительно через декоратор inject можно указывать опциональные, именновые зависимости.

Создание внедряемых типов

Для того чтобы создать тип, который можно будет использовать через DI, необходимо:

  1. Описать интерфейс типа

    export interface IMySolutionType {}

  2. Описать имплементацию и указать декоратор injectable:

    @injectable() export class MySolutionType implements IMySolutionType { constructor(@inject(ICardService$) private _cardService: ICardService) {} // для примера укажем зависимость }

  3. Создать токен типа зависимости:

    export const IMySolutionType$ = createInjectToken<IMySolutionType>('IMySolutionType');

  4. В регистраторе зарегистрировать тип в 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.

Back to top