InversifyJS - 将中间件注入控制器

InversifyJS - Inject middleware into controller

我在节点应用程序中使用快捷装饰器(@GET、@POST...)来使用 inversify-express-utils。

是否可以将中间件注入控制器以与这些装饰器一起使用?

我正在努力实现的示例(不起作用):

export class TestController implements Controller {
    constructor(@inject(TYPES.SomeMiddleware) private someMiddleware: ISomeMiddleware) {}

    @Get('/', this.someMiddleware.someMiddlewhereMethod())
    public test() {
       ...
    }

}

你应该可以使用中间件请参考the following unit tests as an example

更新

我认为这是不可能的,因为装饰器是在声明 class 时执行的。构造函数注入发生在创建 class 实例时(在声明之后)。这意味着,当执行装饰器时,this.someMiddleware 为 null。

恐怕您无法将中间件注入到使用它的 class 中,但您可以执行以下操作:

import { someMiddlewareMethod} from "middleware";

class TestController implements Controller {

    @Get('/', someMiddlewareMethod())
    public test() {
       // ...
    }

}

这不是 InversifyJS 的限制,这是装饰器工作方式造成的限制。

正如@OweR ReLoaDeD 所说,由于装饰器在 TypeScript 中的工作方式,目前您无法使用通过控制器构造函数注入的中间件来做到这一点。

但是,您可以通过将控制器定义包装在接受内核的函数中来实现相同的效果,如下所示:

controller.ts

export function controllerFactory (kernel: Kernel) {

    @injectable()
    @Controller('/')
    class TestController {
        constructor() {}

        @Get('/', kernel.get<express.RequestHandler>('Middleware'))
        testGet(req: any, res: any) {
            res.send('hello');
        }
    }

    return TestController;
}

main.ts

let kernel = new Kernel();

let middleware: express.RequestHandler = function(req: any, res: any, next: any) {
    console.log('in middleware');
    next();
};

kernel.bind<express.RequestHandler>('Middleware').toConstantValue(middleware);

let controller = controllerFactory(kernel);
kernel.bind<interfaces.Controller>(TYPE.Controller).to(controller).whenTargetNamed('TestController');

let server = new InversifyExpressServer(kernel);
// ...

更新

我在 inversify-express-examples repo 中添加了一个示例,展示了使用自定义和第三方中间件的这种方法。