3

I need to create a instance based on a query.

I have an interface like this:

import { GatewaySendMessageDto } from "./dto/gateway-send-message.dto";
import { IGateway } from "./interfaces/IGateway";

export interface GatewayInterface {

    sendMessage(channel: IGateway, data: GatewaySendMessageDto):void

}

and it's the basic method that my classes needs to implement

I create the Factory Class like this

export class GatewayFactory {

    public GatewayFactory(){}

    public getGateway (type) {
        
        let a = GatewayTypesEnum.Telegram;
        let gateway:GatewayInterface = null;
        switch (type){
            case 'Telegram':
                gateway = new TelegramService(??);
                break;
            case GatewayTypesEnum.Discord:
                //gateway = new foo();
                break;
        }
        return gateway;
    }

}

I need to create an instance of telegramService when the type is 'Telegram', but it has a dependecy like:

constructor(
        @InjectModel(Gateway.name) private readonly gatewayModel: Model<Gateway>,
        private bot: Telegraf,        
        private imagesService: ImagesService,

    ) 

obviously, telegramService implements GatewayInterface

so in my GatewayService I could do:

async sendMessageToGatway(){
        let gateway = new GatewayFactory()
        return gateway.getGateway('Telegram').sendMessage();
    }

How can I implement the Factory Pattern method when the service has the dependencies? Thanks

monkeyUser
  • 4,301
  • 7
  • 46
  • 95
  • Try this way get injector https://stackoverflow.com/a/52626099/1716560 and then you can `this.moduleRef.get(TelegramService)`. So you alsow need get `moduleRef` in contructor of GatewayFactory – ktretyak Aug 12 '22 at 20:23
  • @ktretyak I tried to follow your link but inside my factory I get "Nest could not find TelegramService element (this provider does not exist in the current context)" – monkeyUser Aug 15 '22 at 19:57

1 Answers1

2

You factory class should be a service too adding @Injectable() decoractor then you should inject all your service in class constructor and use in you factory method.

@Injectable()
export class GatewayFactory {
  constructor(
    private readonly telegramService: TelegramService,
    private readonly discordService: DiscordService
  ) {}
  public getGateway(type) {
    switch (type) {
      case "Telegram":
        return this.telegramService;
      case "Discord":
        return this.discordService;
      default:
        throw new Error("Invalid service type: " + type);
    }
  }
}