0

I am trying to do some kind of inheritance over some services that I have. I don't really know if it is a good practice or not, anyway I would really like to refactor all the entire app getting new approachs.

Anyways, that's what I have

    ...............................

@Injectable()
export class ApiBaseService {

    ...............................

  constructor(url : string, _logger : LoggerService) {

    ...............................    

 }

    ...............................

And a child class

    ...............................


@Injectable()
export class ApiWhatEverService extends ApiBaseService {

  constructor(private _http: Http) {
    super(environment.apiUrl);
  }

    ...............................

}

The point here is that constructors don't match due to DI related with LoggerService

So my thoughts here is trying to inject the LoggerService in any other way like using injector of angular, but it fails

    ...............................

@Injectable()
export class ApiBaseService {

  apiUrl;
  _logger : LoggerService;

    ...............................

  constructor(url : string) {

    ...............................    


    let injector = ReflectiveInjector.resolveAndCreate([
      LoggerService
    ]);
    this._logger = injector.get(LoggerService);
    //IT DOESN'T GET ALL THE METHOD ASSOCIATED TO LoggerService
    ...............................
  }

    ...............................

}

I would appreciate if someone could help or guide me with that.

Many thanks in advance

ackuser
  • 5,681
  • 5
  • 40
  • 48

1 Answers1

0

Providers are instantiated by the framework. A user cannot provide arguments to provider class constructor. url : string doesn't make sense in injectable classes, it will result in DI error because there's no string provider.

There are several recipes that allow to provide configuration for a provider (see this overview). URL can be provided in configuration provider:

const CONFIG = new InjectionToken<any>('config');
function configFactory() {
  return {
    url: environment.url
  }
}

...
providers: [..., { provide: CONFIG, useFactory: configFactory }]
...

Child providers should augment the list of parent providers in order to pass it with super:

@Injectable()
export class ApiBaseService {
  constructor(
    @Inject(CONFIG) protected config: any,
    protected _logger : LoggerService
  ) {...}
}

@Injectable()
export class ApiWhatEverService extends ApiBaseService {

  constructor(
    @Inject(CONFIG) config: any,
    _logger : LoggerService,
    private _http: Http
  ) {
    super(config, _logger);
  }
}

ReflectiveInjector is generally used in edge cases (it was deprecated in favour of StaticInjector that has additional limitations). It's antipattern here. Wherever possible, existing injector should be used.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565