Inject class implementation into abstract controller implementation based on an interface via NestJS

元气小坏坏 提交于 2021-01-29 07:37:10

问题


I'm currently trying to work out a setup using NestJS injection, but I'm running into errors when trying to run the server.

The problem that I'm running into has to do with me trying to inject a class into a controller which extends an abstract class and I'm trying to set a property of the abstract class in the constructor.

Controller.ts

@Controller()
export class exampleController extends AbstractController {

  constructor(exampleClass: exampleInterface) {
    super(exampleClass);
  }

  @Get()
  getExample(): string {
    return 'Example';
  };
}

AbstractController.ts

export abstract class AbstractController {

  private exampleClass: ExampleInterface;

  constructor(exampleClass: ExampleInterface) {
    this.exampleClass = exampleClass;
  };

When I try to run my server, I get the following error:

Error: Nest can't resolve dependencies of the ExampleController (?). Please make sure that the argument Object at index [0] is available in the AppModule context.

I've added the class implementation to the app.module providers, but even then the error prevents me from running my code.

App.Module.ts

@Module({
  imports: [],
  controllers: [AppController, ExampleController],
  providers: [ExampleClass],
})
export class AppModule {}

ExampleClass.ts

@Injectable()
export class ExampleClass implements ExampleInterface {

  doSomething(): void {
    console.log('Hello World!');
  };
};

I've already tried different setups and looked at some other StackOverflow questions that advise to change up the provider in the app.module, but I haven't found one that worked for me yet. Any advise would be appreciated.


回答1:


Typescript interfaces are a compile time construct (they don't exist at all when the code is actually running), so there is no way for Nest to understand what parameter you're trying to inject.

You're going to have to specify your own Injection token with the provider configuration and then use that in the ExampleController constructor.

providers: [{ provide: 'ExampleToken', useClass: ExampleClass}]

and then you can inject it into your controller using ExampleToken (or whatever makes sense in your app)

@Controller()
export class exampleController extends AbstractController {

  constructor(@Inject('ExampleToken') exampleClass: exampleInterface) {
    super(exampleClass);
  }

  @Get()
  getExample(): string {
    return 'Example';
  };
}


来源:https://stackoverflow.com/questions/63902613/inject-class-implementation-into-abstract-controller-implementation-based-on-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!