Getting instance of service without constructor injection
Yes, ReflectiveInjector.resolveAndCreate()
creates a new and unconnected injector instance.
You can inject Angulars Injector
instance and get the desired instance from it using
constructor(private injector:Injector) { injector.get(MyService);}
You also can store the Injector
in some global variable and than use this injector instance to acquire provided instances for example like explained in https://github.com/angular/angular/issues/4112#issuecomment-153811572
In the updated Angular where ngModules are used, you can create a variable available anywhere in the code:
Add this code in app.module.ts
import { Injector, NgModule } from '@angular/core'; export let AppInjector: Injector; export class AppModule { constructor(private injector: Injector) { AppInjector = this.injector; } }
Now, you can use the AppInjector
to find any service in anywhere of your code.
import {AppInjector} from '../app.module';const myService = AppInjector.get(MyService);
Another approach would consist of defining a custom decorator (a CustomInjectable
to set the metadata for dependency injection:
export function CustomComponent(annotation: any) { return function (target: Function) { // DI configuration var parentTarget = Object.getPrototypeOf(target.prototype).constructor; var parentAnnotations = Reflect.getMetadata('design:paramtypes', parentTarget); Reflect.defineMetadata('design:paramtypes', parentAnnotations, target); // Component annotations / metadata var annotations = Reflect.getOwnMetadata('annotations', target); annotations = annotations || []; annotations.push(annotation); Reflect.defineMetadata('annotations', annotations, target); }}
It will leverage the metadata from the parent constructor instead of its own ones. You can use it on the child class:
@Injectable()export class SomeService { constructor(protected http:Http) { }}@Component()export class BaseComponent { constructor(private service:SomeService) { }}@CustomComponent({ (...)})export class TestComponent extends BaseComponent { constructor() { super(arguments); } test() { console.log('http = '+this.http); }}
See this question for more details: