node.js - NestJS: konstruktorinjektion med abstrakt klass


Jag utvecklar ett NestJS-projekt med TypeScript.

Jag har en abstrakt klass:

export abstract class JobExecutor {

  private readonly name: string;

  constructor(
    // I injected the JobConfig instance in constructor
    protected readonly config: JobConfig,
  ) {
    this.name = this.getName();
  }
  
  abstract getName(): string;

  // non-abstract method also needs to access `config`
  doJob = async ()=> {
    const configMetaData = this.config.metadata;
  }

}

Sedan injiceras min konkreta klass som utvidgar den ovanstående abstrakta klassen själv till en annan anropare, men det är inget problem så jag visar inte det här:

@Injectable()
export class HeavyJobExecutor extends JobExecutor {
   //implement the abstract method
   getName(): string {
       // it accesses the injected `config` from the abstract class,
       // BUT at runtime, this.config is null, why?
       return this.config.heavyjob.name;
   }
}

När jag kör koden får jag ett fel som säger att this.config är null i HeavyJobExecutor. Varför är det så?

Eftersom både abstrakt klass och konkret klass behöver komma åt det där config-instansen föredrar jag att injicera den i den abstrakta klassens konstruktor. Men hur kan jag komma åt config i den konkreta klassen?

Svar #1

Du kan använda anpassade leverantörer

Var du definierar leverantören HeavyJobExecutor

@Module({
  providers: [HeavyJobExecutor],
})
export class SomeExecutorModule {}

ersätt med

@Module({
  providers: [
    {
      provide: JobExecutor,
      useClass: HeavyJobExecutor,
    },
  ],
})
export class SomeExecutorModule {}

Och där du injicerar denna leverantör, specificera typen på den abstrakta klassen

constructor(
   private readonly heavyJobExecutor: JobExecutor
) {}

Du behöver också lägga till Injectable-dekorationen på den abstrakta klassen

@Injectable()
export abstract class JobExecutor

Relaterade artiklar