【问题标题】:How to inject a service in parent class without passing it in constructor? Angular 6如何在父类中注入服务而不将其传递给构造函数?角 6
【发布时间】:2018-10-17 15:33:59
【问题描述】:

我想知道如何在一个抽象类中注入一个具有多个依赖项的服务,该抽象类将被多个类扩展。

以一种更有效的方式,然后将其传递给所有构造函数!

我尝试创建静态的,但如果服务从未被另一个实例化,则永远不会分配单例实例变量

类似这样的:(只是一个例子)

@Injectable({
  providedIn: 'root'
})
export class AnimalService {

  constructor(private http: HttpClient, private userService: UserService) {}

  countTotalInDB(type): number {
    return this.http.get(...);
  }

  getUserAnimals(userId: number) {
    return this.userService.getUser(userId).animals;
  }

}

abstract class Animal {

  constructor() {}

  public getTotalInDataBase(type): number {
    // How to get a instance of AnimalService ?
    return animalService.countTotalInDB(type);
  }

}

export class Cat extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('cat');
  }

}

export class Dog extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('dog');
  }

}

const doggo = new Dog();

console.log(doggo.getTotalInDataBase());

在这种情况下,AnimalService 将使用HttpClientUserService

UserService 将使用更多服务。

那么我怎样才能获得一个看起来像这样const doggo = new Dog(); 的类实例化,它将创建/使用/注入 AnimalService 而不在所有类中传递它?

【问题讨论】:

  • 我不确定有没有办法解决这个问题。我可能会创建一个服务,它本质上是一个用于实例化这些对象的工厂。然后服务可以传递所有依赖项。
  • 您将如何有效地做到这一点?或者你有文档吗?链接?
  • 我的意思是创建一个具有createDog 等方法的服务。该服务可以注入AnimalService 等。然后它可以执行return new Dog(this.animalService)。你仍然会传递给构造函数,但我看不出有什么效率低下。在你的组件中避免像这样的new 实际上可能是有益的——你可以在你的单元测试中模拟createDog
  • 你最后有没有找到实现这个的方法?
  • 是的!我会回答我的问题。

标签: angular typescript dependency-injection


【解决方案1】:

我终于找到了方法。

按照我的例子:

import { inject } from '@angular/core'; // Answer

@Injectable({
  providedIn: 'root'
})
export class AnimalService {

  constructor(private http: HttpClient, private userService: UserService) {}

  countTotalInDB(type): number {
    return this.http.get(...);
  }

  getUserAnimals(userId: number) {
    return this.userService.getUser(userId).animals;
  }

}

abstract class Animal {

  protected animalService: AnimalService; // Answer

  constructor() {
    this.animalService = inject(AnimalService); // Answer
  }

  public getTotalInDataBase(type): number {
    // How to get a instance of AnimalService ?
    return this.animalService.countTotalInDB(type);
  }

}

export class Cat extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('cat');
  }

}

export class Dog extends Animal {

  constructor() {
    super();
  }

  public getTotalInDataBase(): number {
    return super.getTotalInDataBase('dog');
  }

}

const doggo = new Dog();

console.log(doggo.getTotalInDataBase());

它适用于我的情况,希望它也能帮助你!

【讨论】:

  • 您好@The224,您的代码正是我想要的结构,但我收到错误inject() must be called from an injection context@angular/core: ^6.1.10,您将使用哪个版本开发?
  • 您是否在使用@Injectable 注释的服务内进行注入?我使用的是 angular ~6,答案也适用于 6+。
  • 感谢您查看我的消息 @The224,我已经通过将您的示例代码复制/粘贴到我的项目中进行了测试(并且只是模拟了 countTotalInDB/getUserAnimals 响应)来测试我是否可以注入 @987654325 @进入Animal
猜你喜欢
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
  • 2012-08-25
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
相关资源
最近更新 更多