[英]How to achieve component scanning/auto discovery of Controllers using Inversify + inversify-express-utils
I am looking for a way to load my controller classes in Inversify that are annotated with @controller()
from inversify-express-utils
without needing to manage a hand crafted/manually constructed module of imports/exports.我正在寻找一种在 Inversify 中加载我的控制器类的方法,这些类从inversify-express-utils
使用@controller()
进行注释,而无需管理手工制作/手动构建的导入/导出模块。
All of the examples I am seeing seem to indicate that in your entry file you need to import each of your controllers explicitely so that inversify-express-utils
picks up on the @controller
annotations, however this feels like it would be rather tedious for applications of a medium to large size.我看到的所有示例似乎都表明,在您的入口文件中,您需要明确地导入每个控制器,以便inversify-express-utils
接收@controller
注释,但是这对于应用程序来说似乎相当乏味中到大尺寸。
In plain JavaScript I would do something like recursively require each file in a directory at runtime, however I understand that due to the way TypeScript works, this isn't exactly possible?在纯 JavaScript 中,我会在运行时递归地要求目录中的每个文件,但是我理解由于 TypeScript 的工作方式,这不可能完全实现?
Using the inversify-binding-decorators
package, I am able to simply annotate a service with @provide()
and that seems to be enough to have the class added to the IOC container, however that does not seem to be enough for inversify-express-utils
to discover the @controller()
annotations on the class.使用inversify-binding-decorators
包,我可以简单地使用@provide()
注释服务,这似乎足以将该类添加到 IOC 容器中,但是对于inversify-express-utils
似乎还不够inversify-express-utils
来发现类上的@controller()
注释。
Is there a way to achieve auto discovery of these @controller()
annotated classes without manually importing them into a entry file?有没有办法在不手动将它们导入入口文件的情况下实现这些@controller()
注释类的自动发现?
/services/StarwarsNamesService.ts /services/StarwarsNamesService.ts
import { provide } from 'inversify-binding-decorators';
import * as names from 'starwars-names';
import * as matchSorter from 'match-sorter';
@provide(StarwarsNamesService)
export default class StarwarsNamesService {
public getNames(): Array<string> {
return names.all;
}
public getRandomNames(count?: number): Array<string> {
if (!count) { count = 1; }
return names.random(count);
}
public searchNames(term?: string): Array<string> {
return matchSorter(this.getNames(), term);
}
}
/controllers/StarWarsNamesController.ts /controllers/StarWarsNamesController.ts
import { inject } from 'inversify';
import { controller, httpGet } from 'inversify-express-utils';
import StarwarsNamesService from '../../starwars-names/StarwarsNamesService';
@controller('/api/starwars-names')
export default class StarWarsNamesController {
@inject(StarwarsNamesService)
private starwarsNamesService: StarwarsNamesService;
@httpGet('/')
public getAll(): any {
return this.starwarsNamesService.getNames();
}
}
boostrap.ts boostrap.ts
import 'reflect-metadata';
import * as express from "express";
import * as path from 'path';
import { InversifyExpressServer } from 'inversify-express-utils';
import { buildProviderModule } from "inversify-binding-decorators";
import { Container } from 'inversify';
// Has to be explicitly imported otherwise is undiscovered
import './controllers/StarwarsNamesController.ts';
let container = new Container();
container.load(buildProviderModule());
let server = new InversifyExpressServer(container);
let serverInstance = server.build();
serverInstance.listen(3000, () => {
console.log('Server started on port 3000 :)');
});
Thrown Error:抛出错误:
E:\..\..\node_modules\inversify-express-utils\lib\utils.js:10
throw new Error(constants_1.NO_CONTROLLERS_FOUND);
^
Error: No controllers have been found! Please ensure that you have register at least one Controller.
at Object.getControllersFromContainer
...
You can do the following to expose your controllers您可以执行以下操作来公开您的控制器
index.js
or index.ts
file in your controller folder在控制器文件夹中创建index.js
或index.ts
文件export * from "./your controller file path"
添加这样的每个控制器文件export * from "./your controller file path"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.