【问题标题】:How does angular handles dependency injection for multiple services?Angular 如何处理多个服务的依赖注入?
【发布时间】:2020-03-07 19:20:01
【问题描述】:

我创建了一个抽象类,作为我的其他两个服务的基础服务。下面是这个抽象类的代码sn-p:

import { Injectable } from '@angular/core';

export interface Book {
  title: string;
  description: string;
  price: number;
} 
@Injectable({
  providedIn: 'root'
})
export abstract class BaseService {

      constructor() { }

      abstract getBooks(): Book[];

}

那么,下面是两个实现抽象类服务的服务: 第一次服务:

export class NovelService implements BaseService {

      constructor() { }
      getBooks() {
            const novels: Book[] = [
                {
                  title: 'War and peace',
                  description: "War and Peace broadly focuses on Napoleon's invasion of Russia in 1812",
                  price: 550
                }
              ];

            return novels;
        }

}

第二次服务:

export class ReferenceBookService implements BaseService {



constructor() { }
getBooks() {
        const referenceBooks: Book[] = [
            {
              title: 'Spring in Action',
              description: "Spring in Action, Fourth Edition is a hands-on guide to the Spring Framework",
              price: 600
            }
          ];

        return referenceBooks;
    }

}

现在,在我的组件中,单击按钮我需要决定需要注入哪个服务,并相应地执行“getBooks()”函数以在 html 中打印列表。

我尝试在提供者数组中使用“useClass”属性,如下所示:

import { Component, OnInit } from '@angular/core';
import { Book, BaseService } from '../../services/base.service';
import { NovelService } from '../../services/novels-service';
import { ReferenceBookService } from '../../services/reference-book-service';
let IS_NOVEL_MODE = true;
export function setValue(somevalue) {
  IS_NOVEL_MODE = somevalue;
}
@Component({
  selector: 'app-book',
  template: `<div *ngFor="let book of books">
  <h3>{{ book.title }}</h3>
  <p>{{ book.description }}</p>
</div>
<button (click)="changeMode()">click me!</button>`,
  styleUrls: ['./book.component.css'],
  providers: [{provide: BaseService, useClass: IS_NOVEL_MODE ? NovelService : ReferenceBookService}]
})
export class BookComponent implements OnInit { 
      books: Book[];
      isNovelMode = false;
        constructor(private _baseService: BaseService) { }

          ngOnInit() { 
            this.books = this._baseService.getBooks();
          }
          changeMode() {
            setValue(!this.isNovelMode);
          }

}

每次单击按钮时,我都需要一种更新提供程序数组或“useClass”属性的方法。

简而言之,有一个抽象类 BaseService 和“NovelService”和“ReferenceBookService”作为它们的实现,我怎样才能动态地决定将它们中的哪一个注入到我的组件中?

【问题讨论】:

  • 我的回答对你有帮助吗?

标签: angular dependency-injection service autowired


【解决方案1】:

如果您使用providedIn: 'root' 提供服务,那么 Injector 肯定拥有它们,您只需 get 它们即可:

constructor(private injector: Injector) {}
...
this.myService = this.injector.get(MyService);

然后你就不需要注入baseClass了。同时删除@Injectable

【讨论】:

  • 就是这样,干净、简单、高效。
【解决方案2】:

我认为不会,注入发生在组件的创建过程中。 你可以在这里阅读更多细节 https://medium.com/angular-in-depth/angular-dependency-injection-and-tree-shakeable-tokens-4588a8f70d5d

我会以不同的方式来做。 我将创建一项服务,将 URL[或类型] 作为参数,因此您可以动态决定您需要哪种服务

【讨论】:

  • 你能提供你所建议的工作示例吗?
猜你喜欢
  • 2019-03-04
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 2016-08-07
  • 2019-05-15
  • 2016-10-23
  • 2021-11-19
  • 1970-01-01
相关资源
最近更新 更多