@sanex3339

Angular 2 как правильно задать зависимости для синглтон сервиса в bootstrap?

Итак, уже 3-й день бьюсь над проблемой, спрашивал уже и на SO, но пока мне так никто и не помог.

Допустим, есть 2 сервиса синглтона (ServiceA и ServiceB) - хранилища, которые хранят данные на протяжении всего жизненного цикла приложения.
У этих двух сервисов есть зависимость в конструкторе - коллекция CollectionService. Эти 2 сервиса через себя пробрасывают данные в эту коллекцию, в которой данные уже хранятся. Соответственно, для каждого из этих 2-х сервисов, коллекция должна быть своя, т.е. не должна быть синглтоном.
Усложняет задачу то, что один из сервисов, ServiceA должен быть доступен с корректно заинжекченной зависимостью внутри RouteHook'а CanActivate.
И вот тут встает проблема - как это все дело разрулить через bootstrap()?

Я пытался делать так, как указано в документации, с использованием useFactory. Один нюанс - в доках показан пример с созданием объекта без параметров конструктора, у себя я добавляю коллекцию, в кач-ве зависимости.
imports ...

bootstrap(AppComponent, [
    provide(ServiceA, {
        useFactory: () => {
            rerturn new ServiceA(new CollectionService<ServiceADataType>())
        }
    }),
    provide(ServiceB, {
        useFactory: () => {
            rerturn new ServiceB(new CollectionService<ServiceBDataType>())
        }
    })
]);


Такой код выбрасывает ошибку:
Cannot read property 'getOptional' of undefined

Вариант с использованием deps: [CollectionService] сразу отпадает, т.к. нужно тогда указать CollectionService прямо в bootstrap, и тогда коллекция станет синглтоном.

Соотвественно я так и не разрулил данную ситуацию. Пока у меня готов только ServiceA и я временно таки инжекчу CollectionService глобально, но потом надо будет это поправить.

С использованием providers тоже не очень хорошо получается. Да, я могу в каждом компоненте (директиве), где будет выводиться результат ServiceA или ServiceB - прописывать в providers сам сервис и его зависимость:
providers: [ServiceA, CollectionService]

В таком случае зависимости разруливаются.
Но тогда я без понятия, как пробросить ServiceA в RouteHook, т.к. там насколько я понял, получить сервис можно только из Injector'а, который должен быть синглтоном.
В данный момент такой инжектор у меня создается таким способом:
export const AppInjector = (injector?: Injector): Injector => {
    if (injector) {
        appInjectorRef = injector;
    }

    return appInjectorRef;
};

bootstrap(AppComponent, [
   ...
]).then((appRef: ComponentRef) => {
    AppInjector(appRef.injector);
});


В результате, он содержит в себе и разруливает все зависимости которые указаны в bootstrap. Так что, если я уберу из bootstrap CollectionService, оставив только ServiceA - он не сможет разрулить при Injector.get(ServiceA) зависимость CollectionService.

В общем, мб тут помогут, ситуация на самом деле должна быть распространенной.
  • Вопрос задан
  • 420 просмотров
Решения вопроса 1
@sanex3339 Автор вопроса
Мда.

provide(ServiceA, {
        useValue: new ServiceA(new CollectionService<ServiceADataType>())
    })


Понять бы теперь - почему useFactory отдает ошибку
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы