InversifyJS -将中间件注入控制器



我在节点应用程序中使用了使用快捷装饰器(@GET, @POST…)的inversify-express-utils

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

我想达到的目标(不工作)的例子:

export class TestController implements Controller {
    constructor(@inject(TYPES.SomeMiddleware) private someMiddleware: ISomeMiddleware) {}
    @Get('/', this.someMiddleware.someMiddlewhereMethod())
    public test() {
       ...
    }
}

就像@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);
// ...
<标题> 更新

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

您应该能够使用中间件,请参考下面的单元测试作为示例。

<标题> 更新

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

恐怕你不能将中间件注入到使用它的同一个类中,但是你可以这样做:

import { someMiddlewareMethod} from "middleware";
class TestController implements Controller {
    @Get('/', someMiddlewareMethod())
    public test() {
       // ...
    }
}

这不是InversifyJS的限制,这是由装饰器的工作方式引起的。

最新更新