如何将Service注入类(不是组件)

时间:2017-01-02 19:34:10

标签: angular typescript

我想将服务注入到不是组件的类中。

例如

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

此解决方案不起作用(我认为因为MyClass还没有实例化)。

是否有另一种在课堂上使用服务的方式(不是组件)?或者我设计代码的方式是错误的(在类中使用服务而不是组件)

谢谢。

5 个答案:

答案 0 :(得分:34)

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

  1. 你需要
    • @Injectable()添加到MyClass
    • 在组件或NgModule中提供MyClass providers: [MyClass]
  2. 当您在某处注入MyClass时,MyService实例在被DI实例化时(在第一次注入之前)传递给MyClass

    1. 另一种方法是配置自定义注入器,如
    2. 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
      另请参阅Getting dependency from Injector manually inside a directive

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

答案 1 :(得分:17)

不是问题的直接答案,但如果您正在阅读此SO,原因我可能有帮助...

假设您正在使用ng2-translate并且您真的希望您的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
}

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

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

希望这能帮助那些像我一样的人,因为我们有时太聪明了,所以他们要写更多的东西来维护代码=]

(注意:您可能想要设置变量而不是将其作为构造函数方法的一部分的原因是您可能遇到不需要使用该服务的情况,因此始终需要将其传递出来意味着引入从未真正使用的额外导入/代码

答案 2 :(得分:6)

这有点(非常),但是我想我也应该分享我的解决方案。 请注意,这仅适用于Singleton服务(注入到应用程序根目录,而不是组件!),因为它们与您的应用程序一样有效,并且只有一个实例。

首先,为您服务:

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

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

然后在任何课程中:

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

如果您想减少代码混乱并且始终不使用非单一服务,则此解决方案很好。

答案 3 :(得分:5)

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
}

答案 4 :(得分:0)

如果您的服务方法是纯函数,则解决此问题的一种干净方法是在服务中使用静态成员。

您的服务

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