如何将服务注入类(而不是组件)

我想将一个服务注入到一个类 不是成分中。

例如:

我的服务

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();
}
}

我试过了,但是没有用。看起来服务只需要在组件或服务中使用。

Is there a way to use a service in a normal class? or it's a bad practice to use a service in a normal class.

谢谢你。

76239 次浏览

注入只适用于由 Angulars 依赖注入(DI)实例化的类。

  1. 你必须这么做
  • @Injectable()加到 MyClass
  • 在组件或 NgModule 中提供类似于 providers: [MyClass]MyClass

然后在某个地方注入 MyClass时,当通过 DI 实例化 MyService实例时(在第一次注入之前) ,MyService实例被传递给 MyClass

  1. 另一种方法是配置自定义注入器,如

新型静电注射器

constructor(private injector:Injector) {
let childInjector = Injector.create({ providers: [MyClass], parent: this.injector});


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

使用废弃的反射式注入器

constructor(private injector:Injector) {
let resolvedProviders = ReflectiveInjector.resolve([MyClass]);
let childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);


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

这样,myClass将是一个 MyClass实例,由 Angulars DI 实例化,并且 myService将在实例化时注入到 MyClass
参见: 从注入器手动获取指令内部的依赖性

  1. 还有一种方法是自己创建实例:
constructor(ms:myService)
let myClass = new MyClass(ms);

这并不是对这个问题的直接回答,但是如果你正在阅读这篇文章,那么由于我的原因,这篇文章可能会有所帮助..。

假设您正在使用 翻译,并且您确实希望您的 User.ts类具有它。你马上想到的是用 DI 把它放进去,毕竟你是在做 Angular。但是这有点多虑了,你可以直接在构造函数中传递它,或者把它变成一个你从组件中设置的公共变量(你可能在组件中进行了 DI)。

e.g.:

import { TranslateService } from "ng2-translate";


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


// a bunch of awesome User methods
}

然后从一些用户相关的组件,注入了 TransalateService

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

Hopefully this helps those out there like me who were about to write a lot of harder to maintain code because we're too clever sometimes =]

(注意: 你可能想要设置一个变量而不是让它成为你的构造函数方法的一部分的原因是你可能会遇到不需要使用这个服务的情况,所以总是需要传递它将意味着引入额外的导入/代码,而这些导入/代码从来没有真正使用过)

这是一种(非常) ,但我认为我也应该分享我的解决方案。注意,这只能用于 Singleton 服务(在 app root 注入,而不是组件!),因为它们和您的应用程序一样长,而且它们只有一个实例。

首先,为您服务:

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


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

那么在任何课堂上:

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

如果您想减少代码混乱并且不使用非单例服务,那么这个解决方案是很好的。

如果您的服务方法是纯函数,那么解决这个问题的一个简单方法是在您的服务中包含静态成员。

你的服务

import {Injectable} from '@angular/core';
@Injectable()
export class myService{
public static dosomething(){
//implementation => doesn't use `this`
}
}

你的班级

export class MyClass{
test(){
MyService.dosomething(); //no need to inject in constructor
}
}

定位器,服务器

import {Injector} from "@angular/core";


export class ServiceLocator {
static injector: Injector;
}

应用程序模块

@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
}