Cómo inyectar Servicio en clase (no componente)


Quiero inyectar service en una clase que no es componet.

Por ejemplo

Myservice

import {Injectable} from '@angular/core';
@Injectable()
export class myService{
  dosomething(){
    //implementation
  }
}

MyClass

import { myService } from './myService'
export class MyClass{
  constructor(private myservice:myService){

  }
  test(){
     this.myservice.dosomething();
  }
}

Esta solución no funciona (creo que porque MyClass no ha instanciado todavía).

¿Hay otra forma de usar el servicio en clase (no componente)? o está mal cómo diseño el código (para usar el servicio en una clase no componente)

Gracias.

Author: ConnorsFan, 2017-01-02

3 answers

Injections solo funciona con clases que son instanciadas por Angulars dependency injection (DI).

  1. Es necesario
    • añadir @Injectable() a MyClass y
    • proporcionar MyClass como providers: [MyClass] en un componente o NgModule.

Cuando luego inyecta MyClass en algún lugar, una instancia MyService se pasa a MyClass cuando es instanciada por DI (antes de que se inyecte la primera vez).

  1. Un enfoque alternativo es configurar un inyector personalizado como
constructor(private injector:Injector) { 
  let resolvedProviders = ReflectiveInjector.resolve([MyClass]);
  let childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);

  let myClass : MyClass = childInjector.get(MyClass);
}

De esta manera myClass será una instancia MyClass, instanciada por Angulares DI, y myService se inyectará a MyClass cuando se instancie.
Véase también Obtener dependencia del Inyector manualmente dentro de una directiva

  1. Otra forma es crear la instancia usted mismo:
constructor(ms:myService)
let myClass = new MyClass(ms);
 28
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-22 20:17:58

No es una respuesta directa a la pregunta, pero si estás leyendo esto por la razón que soy esto puede ayudar...

Digamos que estás usando ng2-translate y realmente quieres que tu clase User.ts lo tenga. Tu pensamiento inmediato es usar DI para ponerlo, estás haciendo Angular después de todo. Pero eso es un poco de pensar demasiado, usted puede simplemente pasarlo en su constructor, o hacer que sea una variable pública que se establece desde el componente (donde presumiblemente lo hizo DI en).

Ej:

import { TranslateService } from "ng2-translate";

export class User {
  public translateService: TranslateService; // will set from components.

  // a bunch of awesome User methods
}

Luego de algún componente relacionado con el usuario que inyectó TranslateService

addEmptyUser() {
  let emptyUser = new User("", "");
  emptyUser.translateService = this.translateService;
  this.users.push(emptyUser);
}

Esperemos que esto ayude a aquellos por ahí como yo que estaban a punto de escribir un código mucho más difícil de mantener porque somos demasiado inteligentes a veces=]

(NOTA: la razón por la que puede querer establecer una variable en lugar de hacerla parte de su método constructor es que podría tener casos en los que no necesita usar el servicio, por lo que siempre ser requerido para pasarlo significaría introducción de importaciones/código adicionales que nunca se utilizan realmente)

 12
Author: Ryan Crews,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-07 19:52:08

Esto es una especie de ( muy) hacky, pero pensé que compartiría mi solución también. Tenga en cuenta que esto solo funcionará con servicios Singleton (inyectado en la raíz de la aplicación, no componente!), ya que viven tanto como su aplicación, y solo hay una instancia de ellos.

Primero, en tu servicio:

@Injectable()
export class MyService {
    static instance: MyService;
    constructor() {
        MyService.instance = this;
    }

    doSomething() {
        console.log("something!");
    }
}

Luego en cualquier clase:

export class MyClass {
    constructor() {
        MyService.instance.doSomething();
    }
}

Esta solución es buena si desea reducir el desorden de código y no está utilizando servicios que no sean singleton de todos modos.

 1
Author: Kilves,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-03 12:08:14