S
S
sanex33392016-02-20 22:56:27
Angular
sanex3339, 2016-02-20 22:56:27

Angular 2 how to properly set dependencies for singleton service in bootstrap?

So, for the 3rd day I have been struggling with the problem, I have already asked on SO, but so far no one has helped me.
Let's say there are 2 singleton services (ServiceA and ServiceB) - stores that store data throughout the entire life cycle of the application.
These two services have a dependency in the constructor - CollectionService. These 2 services forward data through themselves into this collection, in which the data is already stored. Accordingly, for each of these 2 services, the collection must be its own, i.e. must not be a singleton .
To complicate matters, one of the services, ServiceA, must be available with a correctly injected dependency inside the RouteHook's CanActivate.
And here the problem arises - how to resolve this whole thing through bootstrap ()?
I tried to do as stated in the documentation using useFactory. One caveat - the docks show an example of creating an object without constructor parameters, in my case I add a collection as a dependency.

imports ...

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

This code throws
Cannot read property 'getOptional' of undefined
an deps: [CollectionService]error : then you need to specify the CollectionService directly in bootstrap, and then the collection will become a singleton.
Accordingly, I did not resolve this situation. So far, only ServiceA is ready for me and I temporarily still inject CollectionService globally, but then I will have to fix it.
Using providers is also not very good. Yes, I can in each component (directive), where the result of ServiceA or ServiceB will be displayed, prescribe the service itself and its dependency in providers:
providers: [ServiceA, CollectionService]
In this case, the dependencies are resolved.
But then I have no idea how to forward ServiceA to RouteHook, because there, as far as I understand, you can get the service only from the Injector, which should be a singleton.
At the moment, I create such an injector in this way:
export const AppInjector = (injector?: Injector): Injector => {
    if (injector) {
        appInjectorRef = injector;
    }

    return appInjectorRef;
};

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

As a result, it contains and resolves all the dependencies that are specified in bootstrap. So, if I remove CollectionService from bootstrap, leaving only ServiceA, it will not be able to resolve the CollectionService dependency with Injector.get(ServiceA).
In general, MB will help here, the situation should actually be widespread.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
sanex3339, 2016-02-20
@sanex3339

Hmm.

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

Now I would like to understand why useFactory gives an error

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question