Angular - inject in other way than constructor?
Asked Answered
C

3

3

In Angular, I have a service that has few things injected through the constructor(...). However that service is also at some place created by calling the constructor. Therefore, adding another service it depends on to the parameters would change the API. I'd like to avoid that.

Is there a way to inject a service into another service without adding it to the constructor parameters? E.g. field injection?

import {Inject, Injectable} from "@angular/core";
import {
    Http, Request, ConnectionBackend, RequestOptions, RequestOptionsArgs, Response, Headers,
    RequestMethod
} from "@angular/http";

import {KeycloakService} from "./keycloak.service";
import {Observable} from 'rxjs/Observable';
import {EventBusService} from "../events/event-bus.service";
import {LoadingSomethingFinishedEvent, LoadingSomethingStartedEvent} from "../events/windup-event";

@Injectable()
export class WindupHttpService extends Http {
    constructor(
        _backend: ConnectionBackend,
        _defaultOptions: RequestOptions,
        private _keycloakService: KeycloakService,
        // ----- This is what I want to avoid. -----
        private _eventBus: EventBusService,
    ) {
        super(_backend, _defaultOptions);
    }

    // -------  This is what I am looking for ---------
    //@Inject()
    //private _eventBus: EventBusService;
Champaign answered 20/7, 2017 at 21:41 Comment(1)
Based on your update the short answer is: no, Angular's DI only natively supports constructor injection.Crying
U
6

Yes and no.

You can use the Injector, but the best way is to inject it into the service:

constructor(private injector: Injector) {
        let httpService: Http = this.injector.get(Http);
}

More about Injector can be found here: https://angular.io/api/core/Injector

Here is also usable link, as @DBosley mentioned: https://angular.io/guide/dependency-injection#appendix-working-with-injectors-directly

Underlay answered 20/7, 2017 at 21:49 Comment(2)
Here are some good examples: angular.io/guide/…Tella
@Dbosley Thanks for this link :)Underlay
C
4

You can do this within Angular's DI using factory providers:

injectFields(dependency: SomeDependency) {
  let service = new FieldInjectedService();
  service.dependency = dependency;
  return service;
}

...

providers: [
  { provide: FieldInjectedService, useFactory: injectFields, deps: [SomeDependency] },
  ...
]

Here the FieldInjectedService doesn't have any constructor parameters, but must have its dependency property set to be any use. The downside, of course, is that nothing here requires you to set those fields, so you could easily create an invalid instance of the service.

Crying answered 20/7, 2017 at 21:50 Comment(0)
S
2

Dependencies field injection comes with angular 14:

import { Component, inject } from '@angular/core';

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.scss']
})
export class DemoComponent {
  private _service = inject(Service);
}

see documentation

Synchronize answered 23/2, 2023 at 14:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.