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

Ele*_*lec 61 typescript angular

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

例如

为MyService

import {Injectable} from '@angular/core';
@Injectable()
export class myService{
  dosomething(){
    //implementation
  }
}
Run Code Online (Sandbox Code Playgroud)

我的课

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

  }
  test(){
     this.myservice.dosomething();
  }
}
Run Code Online (Sandbox Code Playgroud)

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

有没有其他方法在课堂上使用服务(而不是组件)?或者我设计代码的方式是错误的(在类中使用服务而不是组件)

谢谢.

Gün*_*uer 39

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

  1. 你需要
    • 添加@Injectable()MyClass
    • 提供MyClassproviders: [MyClass]部件或NgModule.

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

  1. 另一种方法是配置自定义注入器
constructor(private injector:Injector) { 
  let resolvedProviders = ReflectiveInjector.resolve([MyClass]);
  let childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);

  let myClass : MyClass = childInjector.get(MyClass);
}
Run Code Online (Sandbox Code Playgroud)

这种方式myClass将是一个MyClass实例,由Angulars DI实例化,并在实例化时myService注入MyClass.
另请参阅在指令内手动获取Injector的依赖关系

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

  • 当然,但有时它仍然有意义,知道什么是可能的总是好的 (7认同)
  • 我认为向独立类注入服务是一种反模式。 (2认同)

Rya*_*ews 22

不是问题的直接答案,但是如果你正在阅读这个SO,我可能会帮助...

假设你正在使用ng2-translate,你真的希望你的User.ts班级能够拥有它.你立即想到的是使用DI来装入它,毕竟你正在做Angular.但这有点过分思考它,你可以在你的构造函数中传递它,或者使它成为你从组件设置的公共变量(你可能在那里做了DI).

例如:

import { TranslateService } from "ng2-translate";

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

  // a bunch of awesome User methods
}
Run Code Online (Sandbox Code Playgroud)

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

addEmptyUser() {
  let emptyUser = new User("", "");
  emptyUser.translateService = this.translateService;
  this.users.push(emptyUser);
}
Run Code Online (Sandbox Code Playgroud)

希望这能帮助那些像我一样的人,因为我们有时候太聪明了=

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

  • 也许让 translateService 成为类构造函数中的必需参数更有意义?这种模式更符合 DI 模式恕我直言。 (2认同)

Jul*_*ien 16

定位器.service.ts

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

export class ServiceLocator {
    static injector: Injector;
}
Run Code Online (Sandbox Code Playgroud)

app.module.ts

@NgModule({ ... })

export class AppModule {
    constructor(private injector: Injector) {
        ServiceLocator.injector = injector;
    }
 }
Run Code Online (Sandbox Code Playgroud)

小马模型.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
}
Run Code Online (Sandbox Code Playgroud)


Kil*_*ves 7

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

首先,为您服务:

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

    doSomething() {
        console.log("something!");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在任何班级:

export class MyClass {
    constructor() {
        MyService.instance.doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

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