Angular:我们可以删除所有基于构造函数的注入吗?

问题描述 投票:0回答:1

最近,Angular 进行了迁移,用

inject
函数替换基于构造函数的注入:
https://angular.dev/reference/migrations/inject-function

在大多数情况下,它很简单并且明显有好处:

// before
@Injectable({ providedIn: 'root' })
export class SomeSearchService {
  constructor(
    @Inject(SEARCH_DUE_TIME)
    private readonly dueTime: number,
    private readonly repositoryService: SomeRepositoryService
  ) {}

// after
@Injectable({ providedIn: 'root' })
export class SomeSearchService {
  private readonly dueTime = inject(SEARCH_DUE_TIME);
  private readonly repositoryService= inject(SomeRepositoryService);

但是,

inject
函数可以涵盖所有基于构造函数的注入用法吗?
特别是
useFactory

为了说明这一点,我有:

// print.service.ts
@Injectable()
export class PrintService implements IPrintService {
  constructor(
    @Inject(DATA_SERVICE)
    private readonly dataService: IDataService,
    private readonly logger: LoggingService,
    ...
  ) {}

// tokens.ts
export const DATA_SERVICE = new InjectionToken<IDataService>('DATA_SERVICE');
export const FOO_PRINT_SERVICE = new InjectionToken<IPrintService>('FOO_PRINT_SERVICE');
export const BAR_PRINT_SERVICE = new InjectionToken<IPrintService>('BAR_PRINT_SERVICE');

// app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    {
      provide: FOO_PRINT_SERVICE,
      useFactory: (dataService: IDataService, logger: LoggingService) => new PrintService(dataService, logger),
      deps: [FOO_DATA_SERVICE, LoggingService],
    },
    {
      provide: BAR_PRINT_SERVICE ,
      useFactory: (dataService: IDataService, logger: LoggingService) => new PrintService(dataService, logger),
      deps: [BAR_DATA_SERVICE, LoggingService],
    },
    ...,
  ],
};

有没有办法同时使用

inject
useFactory

这样我就可以删除我的
constructor
中的
PrintService
声明?

angular typescript dependency-injection
1个回答
0
投票

是的,我们可以互换使用它们。

我们有像

skipSelf
Optional
Self
Host
这样的注入装饰器,它们可以作为包含这些属性的对象的第二个参数提供。

fooPrintService = inject(FOO_PRINT_SERVICE, {
  host: false,
  optional: false,
  self: false,
  skipSelf: false,
});

从你的问题角度来看,你需要做的就是将注入令牌传递给

inject
方法,它可以在DI中检测到它。

import { Component, InjectionToken, Injectable, inject } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

export class PrintService {
  constructor(public arg: string) {}
}

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    {{fooPrintService.arg}} | {{barPrintService.arg}}
  `,
})
export class App {
    fooPrintService = inject(FOO_PRINT_SERVICE, {
      host: false,
      optional: false,
      self: false,
      skipSelf: false,
    });
  barPrintService = inject(BAR_PRINT_SERVICE);
  name = 'Angular';
}
export const DATA_SERVICE = new InjectionToken<any>('DATA_SERVICE');
export const FOO_PRINT_SERVICE = new InjectionToken<any>('FOO_PRINT_SERVICE');
export const BAR_PRINT_SERVICE = new InjectionToken<any>('BAR_PRINT_SERVICE');

bootstrapApplication(App, {
  providers: [
    {
      provide: FOO_PRINT_SERVICE,
      useFactory: () => new PrintService('foo'),
    },
    {
      provide: BAR_PRINT_SERVICE,
      useFactory: () => new PrintService('bar'),
    },
  ],
});

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.