Quero injetar um serviço em uma classe que não seja um componente .
Por exemplo:
Myservice
import {Injectable} from '@angular/core';
@Injectable()
export class myService {
dosomething() {
// implementation
}
}
Minha classe
import { myService } from './myService'
export class MyClass {
constructor(private myservice:myService) {
}
test() {
this.myservice.dosomething();
}
}
Esta solução não funciona (acho que porque MyClass
ainda não foi instanciada).
Existe outra maneira de usar um serviço em uma classe (não componente)? Ou você consideraria meu design de código inadequado (para usar um serviço em uma classe que não é um componente)?
Obrigado.
fonte
private
não é necessário, poisinjector
não é usado fora do construtor, portanto, não é necessário manter uma referência em um campo.Não é uma resposta direta à pergunta, mas se você está lendo este SO pelo motivo que estou, isso pode ajudar ...
Digamos que você esteja usando o ng2-translate e realmente deseja que sua
User.ts
classe o tenha. Seu pensamento imediato é usar DI para colocá-lo, você está fazendo Angular, afinal. Mas isso é meio que pensar demais, você pode simplesmente passar isso em seu construtor, ou torná-lo uma variável pública que você definiu a partir do componente (onde você presumivelmente fez o DI).por exemplo:
import { TranslateService } from "ng2-translate"; export class User { public translateService: TranslateService; // will set from components. // a bunch of awesome User methods }
em seguida, de algum componente relacionado ao usuário que injetou TranslateService
addEmptyUser() { let emptyUser = new User("", ""); emptyUser.translateService = this.translateService; this.users.push(emptyUser); }
Espero que isso ajude aqueles que estão por aí, como eu, que estava prestes a escrever um código muito mais difícil para manter o código porque às vezes somos muito espertos =]
(NOTA: o motivo pelo qual você pode querer definir uma variável em vez de torná-la parte de seu método de construtor é que você pode ter casos em que não precisa usar o serviço, portanto, ser sempre solicitado a passá-lo significaria introduzir importações extras / código que nunca é realmente usado)
fonte
translateService
um get / set onde oget
lança um erro significativo em vez de uma exceção NullReference se você se esqueceu de defini-loIsso é meio ( muito ) hacky, mas pensei em compartilhar minha solução também. Observe que isso só funcionará com serviços Singleton (injetados na raiz do aplicativo, não no componente!), Uma vez que eles duram tanto quanto o seu aplicativo e há apenas uma instância deles.
Primeiro, em seu serviço:
@Injectable() export class MyService { static instance: MyService; constructor() { MyService.instance = this; } doSomething() { console.log("something!"); } }
Então, em qualquer aula:
export class MyClass { constructor() { MyService.instance.doSomething(); } }
Esta solução é boa se você deseja reduzir a confusão de código e não está usando serviços não singleton de qualquer maneira.
fonte
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 }
fonte
injector.get()
chamada para o módulo funcionará (assumindo um serviço sem estado para que várias classes possam "compartilhar" a mesma instância)?Se seus métodos de serviço forem funções puras, uma maneira limpa de resolver isso é ter membros estáticos em seu serviço.
seu serviço
import {Injectable} from '@angular/core'; @Injectable() export class myService{ public static dosomething(){ //implementation => doesn't use `this` } }
sua classe
export class MyClass{ test(){ MyService.dosomething(); //no need to inject in constructor } }
fonte