typescript 如何将服务注入类(而非组件)

7dl7o3gd  于 2023-01-27  发布在  TypeScript
关注(0)|答案(6)|浏览(111)

我想将一个服务注入到一个不是组件的类中。
例如:

  • 我的服务 *
import {Injectable} from '@angular/core';
@Injectable()
export class myService {
  dosomething() {
    // implementation
  }
}
  • 我的班级 *
import { myService } from './myService'
export class MyClass {
  constructor(private myservice:myService) {

  }
  test() {
     this.myservice.dosomething();
  }
}

我试过了,但不起作用。看起来服务只需要在组件或服务中使用。
有没有办法在普通类中使用服务?或者在普通类中使用服务是一种不好的做法。
谢谢你。

bn31dyow

bn31dyow1#

注入只适用于通过Angulars依赖注入(DI)示例化的类。
1.你需要

  • @Injectable()加到MyClass,然后
  • 在组件或NgModule中提供类似于providers: [MyClass]MyClass

当您在某处注入MyClass时,MyService示例在被DI示例化时(在第一次注入之前)被传递给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
另请参见在指令内手动获取Injector的依赖关系
1.还有一种方法是自己创建示例:

constructor(ms:myService)
let myClass = new MyClass(ms);
5cnsuln7

5cnsuln72#

不是一个直接的答案的问题,但如果你读这篇文章的原因,我是这可能会有帮助...
假设你正在使用ng2-translate,并且你真的希望你的User.ts类拥有它。你的第一React是使用DI把它放进去,毕竟你在使用Angular。但是这有点想多了,你可以直接在你的构造函数中传递它,或者让它成为一个公共变量,你从组件中设置它(你可能是在组件中使用DI的)。
例如:

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

希望这能帮助那些像我一样将要写很多难以维护的代码的人,因为我们有时太聪明了=]
(NOTE:您可能希望设置变量而不是将其作为构造函数方法的一部分的原因是,您可能会遇到不需要使用服务的情况,因此总是要求传入它将意味着引入从未真正使用过的额外导入/代码)

bvhaajcl

bvhaajcl3#

这有点(非常)笨拙,但我想我也应该分享一下我的解决方案。注意,这只适用于Singleton服务(在应用根注入,而不是组件!),因为它们与应用的寿命一样长,而且它们只有一个示例。
首先,在您的服务中:

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

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

那么在任何一门课上:

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

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

mhd8tkvw

mhd8tkvw4#

定位器.服务.ts

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

export class ServiceLocator {
    static injector: Injector;
}

应用程序模块.ts

@NgModule({ ... })

export class AppModule {
    constructor(private injector: Injector) {
        ServiceLocator.injector = injector;
    }
 }

部件型号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
}
mnemlml8

mnemlml85#

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

您的服务

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

mw3dktmi6#

从Angular 14开始,你可以使用inject函数,但是它只能在构造函数中调用。

import { myService } from './myService'
export class MyClass {
  private myservice: myService
  constructor() {
    this.myservice = inject(myService);
  }
  test() {
     this.myservice.dosomething();
  }
}

别处

import { MyClass } from './myClass'
@component()
export class MyComponent {
  constructor() {
    const myClass = new MyClass();
  }
}

相关问题