Angular 2 - Inject a dependency into a decorator factory Angular 2 - Inject a dependency into a decorator factory angular angular

Angular 2 - Inject a dependency into a decorator factory


Currently, to inject dependencies into my decorators (and other extra module classes) I'm using this workaround:

import {Injectable, Injector} from "@angular/core";@Injectable()export class ExtraModuleInjector {  private static injector;  public static get(token: any) {    if (ExtraModuleInjector.injector) {      return ExtraModuleInjector.injector.get(token);    }  }  constructor(public injector: Injector) {    ExtraModuleInjector.injector = injector;  }}

After being injected to root component, it allows to use static get method to get dependencies during runtime functions execution.Still looking for better solution.


It's a bit tricky to do this, because decorators are executed at build time, not at the runtime. When decorator is executed, there's no instance of the class.

Back in ng2.beta.10, I used this to get the data from service (don't think you can from component, but I could be wrong...):

// some-route.ts@CanActivate((next, prev) => {  let store: any = getSingleton(Store);})// injector.tsimport {Injector} from 'angular2/core'let appInjectorRef: Injector;export const appInjector = (injector?: Injector) => {  if (injector)    appInjectorRef = injector;  return appInjectorRef;}export function getSingleton(token: any) {  let injector: Injector = appInjector();  return injector.get(token);}

..to be honest, looking at this code now I have no ide how it works (; But I know it did back then. Not sure what's the status now, or if there were any breaking changes since beta.10 related to the Injector and ApplicationRef...


One way to do it in Angular 7 is:

app.module.ts

import { setInjector } from './service/inj.service';@NgModule({..})export class AppModule {  constructor(i: Injector) {    setInjector(i)  }}

decorator.service.ts

import { Injectable, Injector } from '@angular/core';let injector: Injector;export const setInjector = (i: Injector)=>{  injector = i}export function mydecorator(arg:any){  let service: SomeServiceWhichNeedsToBeInjected  return (target, key, descriptor)=>{    if(descriptor === undefined) {      descriptor = Object.getOwnPropertyDescriptor(target, key)    }    var originalMethod = descriptor.value    descriptor.value = function () {      if(!loading){        service= injector.get(SomeServiceWhichNeedsToBeInjected)      }      //do something with service      return originalMethod.apply(this, arguments)    }    return descriptor;  }}

other.service.ts

@mydecorator('somearg')decoratedmethod(arg1){  //..}