Nestjs 动态服务调用-IOC

Nestjs 动态服务调用-IOC,nestjs,Nestjs,如何从控制器动态调用服务的方法(从哈希映射中查找): 注册服务 import { Injectable } from '@nestjs/common'; import { CacheService } from '../cache/cache.service'; import { LoggerService } from '../../config/logger/logger.service'; @Injectable() export class RegistrationService {

如何从控制器动态调用服务的方法(从哈希映射中查找):

注册服务

import { Injectable } from '@nestjs/common';
import { CacheService } from '../cache/cache.service';
import { LoggerService } from '../../config/logger/logger.service';

@Injectable()
export class RegistrationService {

  constructor(private readonly cache: CacheService,
    private readonly logger: LoggerService) {
  }

  async process() {
    this.logger.info(`RegistrationService - testThis - hit!`);
  }

}
app.controller.ts

import { Controller, Get, Res } from '@nestjs/common';
import { RegistrationService } from './modules/campaignOne/registration.service';

const SCREENS = {
  'start': 'this.registration.process'
};

@Controller()
export class AppController {
  constructor(private readonly registration: RegistrationService) {}

  @Get('test')
  async test(@Res() res: any): any {
    await eval(SCREENS['start'])();
    return Promise.resolve('ok');    
  }
}
等待评估时(屏幕['start'])()时,调用该方法,但在
this.logger..
处抛出错误,因为它无法解析记录器

其思想是拥有多个提供者,控制器中的逻辑将决定动态调用哪个提供者

我知道问题和解决方案在于依赖注入和IOC——但我不知道如何解决


请帮忙?

我会用工厂方法来处理这个问题

首先创建一个接口来定义您想要的“动态”服务的形状

//IService.ts

export interface IService {
    invoke(): Promise<void>;
}
现在在您的模块中,注入工厂

import { Controller, Get, Res } from '@nestjs/common';
import { ScreenFactory } from './modules/ScreenFactory';

@Controller()
export class AppController {

    constructor(private readonly screenFactory: ScreenFactory) {}

    @Get('test')
    async test(@Res() res: any): any {

        //await eval(SCREENS['start'])();
        const service: IService = this.screenFactory.getService('start');
        await service.invoke();

        return Promise.resolve('ok');
    }
}
这是很多伪代码,但这是我通常处理“每个请求我需要不同的东西”类型场景的方式

//ScreenFactory.ts

import { Injectable } from '@nestjs/common';
import { RegistrationService } from './modules/campaignOne/registration.service';

@Injectable()
export class ScreenFactory {

    private readonly cache: CacheService;
    private readonly logger: LoggerService;

    constructor(cache: CacheService, logger: LoggerService) {
        this.cache = cache;
        this.logger = logger;
    }

    public getService(screenName: string) : IService {

        switch(screenName) {
            case 'start': return new RegistrationService(this.cache, this.logger);
            default: throw new Error('No service defined for the given screen');
        }

    }
}
import { Controller, Get, Res } from '@nestjs/common';
import { ScreenFactory } from './modules/ScreenFactory';

@Controller()
export class AppController {

    constructor(private readonly screenFactory: ScreenFactory) {}

    @Get('test')
    async test(@Res() res: any): any {

        //await eval(SCREENS['start'])();
        const service: IService = this.screenFactory.getService('start');
        await service.invoke();

        return Promise.resolve('ok');
    }
}