Before RC5 I was using appref injector as a service locator like this:
Startup.ts
bootstrap(...) .then((appRef: any) => { ServiceLocator.injector = appRef.injector; });
ServiceLocator.ts
export class ServiceLocator { static injector: Injector; }
components:
let myServiceInstance = <MyService>ServiceLocator.injector.get(MyService)
Now doing the same in bootstrapModule().then() doesn't work because components seems to start to execute before the promise.
Is there a way to store the injector instance before components load?
I don't want to use constructor injection because I'm using the injector in a base component which derived by many components and I rather not inject the injector to all of them.
The Container (a.k.a. JDisc container) implements a dependency injection framework that allows components to declare arbitrary dependencies on configuration and other components in the application. This document explains how to write a container component that depends on another component.
Injectors are data structures that store instructions detailing where and how services form. They act as intermediaries within the Angular DI system. Module, directive, and component classes contain metadata specific to injectors. A new injector instance accompanies every one of these classes.
For today's TypeScript and Angular 5, avoiding WARNING in Circular dependency detected
when importing the global injector, first declare a helper, e.g. app-injector.ts
:
import {Injector} from '@angular/core'; /** * Allows for retrieving singletons using `AppInjector.get(MyService)` (whereas * `ReflectiveInjector.resolveAndCreate(MyService)` would create a new instance * of the service). */ export let AppInjector: Injector; /** * Helper to set the exported {@link AppInjector}, needed as ES6 modules export * immutable bindings (see http://2ality.com/2015/07/es6-module-exports.html) for * which trying to make changes after using `import {AppInjector}` would throw: * "TS2539: Cannot assign to 'AppInjector' because it is not a variable". */ export function setAppInjector(injector: Injector) { if (AppInjector) { // Should not happen console.error('Programming error: AppInjector was already set'); } else { AppInjector = injector; } }
Next, in your AppModule
, set it using:
import {Injector} from '@angular/core'; import {setAppInjector} from './app-injector'; export class AppModule { constructor(injector: Injector) { setAppInjector(injector); } }
And wherever needed, use:
import {AppInjector} from './app-injector'; const myService = AppInjector.get(MyService);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With