angular 如何处理多个服务的依赖注入?
How does angular handles dependency injection for multiple services?
我创建了一个抽象 class 作为我的其他两个服务的基础服务。以下是此摘要的代码片段 class:
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[];
}
然后,以下是实现抽象 class 服务的两个服务:
第一服务:
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 中打印列表。
我尝试在 providers 数组中使用 "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" 属性。
简而言之,有一个抽象的 class BaseService 和 "NovelService" & "ReferenceBookService" 作为它们的实现,我如何动态地决定注入其中一个在我的组件中?
我认为不是,注入发生在组件的创建过程中。
您可以在此处阅读更多详细信息
https://medium.com/angular-in-depth/angular-dependency-injection-and-tree-shakeable-tokens-4588a8f70d5d
我会用一些不同的方式来做。
我会创建一项服务,将 URL[或类型] 作为参数,这样您就可以动态决定您需要哪个服务
如果您使用 providedIn: 'root'
作为您的服务,那么 Injector 肯定有它们,您可以简单地 get
它们:
constructor(private injector: Injector) {}
...
this.myService = this.injector.get(MyService);
然后你不需要注入baseClass。同时从中删除 @Injectable
我创建了一个抽象 class 作为我的其他两个服务的基础服务。以下是此摘要的代码片段 class:
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[];
}
然后,以下是实现抽象 class 服务的两个服务: 第一服务:
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 中打印列表。
我尝试在 providers 数组中使用 "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" 属性。
简而言之,有一个抽象的 class BaseService 和 "NovelService" & "ReferenceBookService" 作为它们的实现,我如何动态地决定注入其中一个在我的组件中?
我认为不是,注入发生在组件的创建过程中。 您可以在此处阅读更多详细信息 https://medium.com/angular-in-depth/angular-dependency-injection-and-tree-shakeable-tokens-4588a8f70d5d
我会用一些不同的方式来做。 我会创建一项服务,将 URL[或类型] 作为参数,这样您就可以动态决定您需要哪个服务
如果您使用 providedIn: 'root'
作为您的服务,那么 Injector 肯定有它们,您可以简单地 get
它们:
constructor(private injector: Injector) {}
...
this.myService = this.injector.get(MyService);
然后你不需要注入baseClass。同时从中删除 @Injectable