Quiero inyectar un servicio en una clase que no es un componente .
Por ejemplo:
Myservice
import {Injectable} from '@angular/core';
@Injectable()
export class myService {
dosomething() {
// implementation
}
}
Mi clase
import { myService } from './myService'
export class MyClass {
constructor(private myservice:myService) {
}
test() {
this.myservice.dosomething();
}
}
Esta solución no funciona (creo que porque MyClass
aún no se ha creado una instancia).
¿Hay otra forma de utilizar un servicio en una clase (no un componente)? ¿O consideraría que el diseño de mi código es inapropiado (para usar un servicio en una clase que no es un componente)?
Gracias.
fuente
private
no es necesario, porqueinjector
no se usa fuera del constructor, por lo tanto, no es necesario mantener una referencia en un campo.No es una respuesta directa a la pregunta, pero si está leyendo esto SO por la razón por la que soy, esto puede ayudar ...
Digamos que estás usando ng2-translate y realmente quieres que tu
User.ts
clase lo tenga. Su pensamiento inmediato es usar DI para ponerlo, después de todo, está haciendo Angular. Pero eso es como pensarlo demasiado, puede simplemente pasarlo en su constructor, o convertirlo en una variable pública que estableció desde el componente (donde presumiblemente lo hizo DI).p.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); }
Espero que esto ayude a aquellos que, como yo, estaban a punto de escribir un código mucho más difícil de mantener porque a veces somos demasiado inteligentes =]
(NOTA: la razón por la que es posible que desee establecer una variable en lugar de convertirla en parte de su método de constructor es que podría haber casos en los que no necesite usar el servicio, por lo que siempre se le solicitará que la pase significaría introducir importaciones adicionales / código que nunca se usa realmente)
fuente
translateService
un get / set dondeget
arroje un error significativo en lugar de una excepción NullReference si olvidó configurarloEsto es un poco ( muy ) hacky, pero pensé en compartir mi solución también. Tenga en cuenta que esto solo funcionará con los servicios de Singleton (inyectados en la raíz de la aplicación, no en el componente), ya que viven tanto como su aplicación, y solo hay una instancia de ellos.
Primero, a su 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.
fuente
locator.service.ts
import {Injector} from "@angular/core"; export class ServiceLocator { static injector: Injector; }
app.module.ts
@NgModule({ ... }) export class AppModule { constructor(private injector: Injector) { ServiceLocator.injector = injector; } }
poney.model.ts
export class Poney { id: number; name: string; color: 'black' | 'white' | 'brown'; service: PoneyService = ServiceLocator.injector.get(PoneyService); // <--- HERE !!! // PoneyService is @injectable and registered in app.module.ts }
fuente
injector.get()
llamada al módulo (asumiendo un servicio sin estado para que varias clases puedan "compartir" la misma instancia)?Si sus métodos de servicio son funciones puras, una forma limpia de resolver esto es tener miembros estáticos en su servicio.
tu servicio
import {Injectable} from '@angular/core'; @Injectable() export class myService{ public static dosomething(){ //implementation => doesn't use `this` } }
Tu clase
export class MyClass{ test(){ MyService.dosomething(); //no need to inject in constructor } }
fuente