Цель
Я хочу написать функциональный модуль, который использует сервис.Этот функциональный модуль не должен быть связан с реализацией этого сервиса, а скорее ожидает, что он реализует интерфейс, и все.
Предостережения и следствия
Предостережение: интерфейс, который должна реализовать служба, не будет определяться этим модулем.
Следствие: Где должен быть определен этот интерфейс?
Нет поставщика для InjectionToken
Функциональный модуль предназначен для использования во многих приложениях в нашей организации.Каждый может реализовать интерфейс для требуемого сервиса по-своему.Если появится новый вариант использования, интерфейс может измениться и запросить изменения в функциональном модуле.
Дизайн, на котором мы остановились, поместил этот интерфейс в общую библиотеку.
ThisВ статье показано, что использование InjectionToken
вызывает следующую ошибку 'NullInjectorError: Нет поставщика для InjectionToken ... `
Я создал StackBlitz пример , который иллюстрирует вышеуказанную настройкуи выпуск.
Исследования
В статье 1010 * выше *1033* описывается, как OpaqueToken
был разработан для предотвращения случайного столкновения этих строк.Добавим, что позже InjectionToken
обернул OpaqueToken
для добавления дополнительной поддержки машинописи.
Я хотел бы, чтобы поддержка машинописи была для меня и моей команды, но с токеном, который допускает контролируемое столкновение.
Минимальный воспроизводимый пример
См. Этот StackBlitz Контролируемый токен столкновения
Неоптимальное решение
Приведенный выше пример можно исправить, если InjectionToken
заменить на строку.
Измените следующие два (идентичные файлы) следующим образом:
- / app / external-feature / lib / shared / i-shared.service.ts
- /app / internal-adapter / shared / i-shared.service.ts
export const I_SHARED_SERVICE = new InjectionToken<ISharedService>('i-shared-service.shared');
=>
export const I_SHARED_SERVICE = 'i-shared-service.shared';
В результате потеря поддержки машинописи.Это похоже на шаг назад.