Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing injector instance for use in components

Tags:

angular

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.

like image 848
dstr Avatar asked Sep 09 '16 10:09

dstr


People also ask

What is a component in dependency injection?

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.

What are the roles of an injector in an angular application?

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.


1 Answers

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); 
like image 184
Arjan Avatar answered Oct 03 '22 08:10

Arjan