InversifyJS:从容器中检索对象时出错
我使用InversifyJS来设置某种dynamic绑定并在NodeJS上运行它。 我遇到的问题是我得到的错误,但没有消息,只有一个堆栈跟踪。
Main
类
export class Main { public static getCalculator(config: string): Calculator { try { var container: Container = new KeyFeatureContainer(config).getContainer(); debugger; // error here ! return container.get<Calculator>(TYPES.Calculator); } catch (error) { debugger; return null; } } }
这个类用一个json
string调用KeyFeatureContainer
,用来configuration所有的绑定(以一种dynamic的方式),然后检索容器。
KeyFeatureContainer
类
export class KeyFeatureContainer { private _container: Container; public constructor(config: string) { var jsonConfig: any[] = JSON.parse(config); this._container = new Container(); this._container.bind<Calculator>(TYPES.Calculator).to(KeyFeatureCalculator); for (var i = 0; i < jsonConfig.length; i++) { if (jsonConfig[i].active) { this.parseConfigKeyFeatures(jsonConfig[i].id); this.parseConfigParams(jsonConfig[i].params); } } } public getContainer(): Container { debugger; return this._container; } private parseConfigKeyFeatures(id: string): void { var keyFeatureContainerModule: ContainerModule = rootContainer.get<KeyFeatureContainerModule>(id).getContainerModule(); if (keyFeatureContainerModule != null) this._container.load(keyFeatureContainerModule); } private parseConfigParams(params: Array<{ name: string, value: any }>): void { for (var param of params) this._container.bind(param.name).to(param.value); } }
这个类接收json
configuration并在一个ID之后加载一个包含接口和具体实现之间绑定的ContainerModule
。 rootContainer
指定要在一个ID之后检索的ContainerModule
。
rootContainer
var rootContainer: Container = new Container(); rootContainer.bind<KeyFeatureContainerModule>(KEYFEATURES.DrugHoliday).to(DrugHolidayContainerModule); rootContainer.bind<KeyFeatureContainerModule>(KEYFEATURES.MissingDay).to(MissingDayContainerModule); export default rootContainer;
和相关的ContainerModule
(第二个是相同的,只是每个PARAMS不同)
@injectable() export class MissingDayKeyFeature implements KeyFeature { @inject(PARAMS.MissingDayParams.NbIntakesLimit) private _nbIntakesLimit: number; @inject(PARAMS.MissingDayParams.ExtraParamA) private _extraParamA: any; @inject(PARAMS.MissingDayParams.ExtraParamB) private _extraParamB: any; public init(): void { console.log("init() at MissingDay"); console.log("nbIntakesLimit = " + this._nbIntakesLimit); console.log("extraParamA = " + this._extraParamA); console.log("extraParamB = " + this._extraParamB); } public calculate(): void { console.log("calculate() at MissingDay"); } public finish(): void { console.log("finish() at MissingDay"); } } @injectable() export class MissingDayContainerModule implements KeyFeatureContainerModule { public getContainerModule(): ContainerModule { return new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind) => { bind<KeyFeature>(TYPES.KeyFeature).to(MissingDayKeyFeature); }); } }
最后, ServiceIdentifiers
用来设置整个(分隔文件)
let TYPES = { KeyFeature: "KeyFeature", Calculator: "Calculator" } export default TYPES; let PARAMS = { DrugHolidayParams: { NbDaysLimit: "nbDaysLimit", ExtraParamA: "extraParamDHA", ExtraParamB: "extraParamDHB" }, MissingDayParams: { NbIntakesLimit: "nbIntakesLimit", ExtraParamA: "extraParamMDA", ExtraParamB: "extraParamMDB" } } export default PARAMS; let KEYFEATURES = { MissingDay: "MissingDayKeyFeature", DrugHoliday: "DrugHolidayKeyFeature" } export default KEYFEATURES;
最后是JSON
input(为了方便而格式化)
[{ "id": "DrugHolidayKeyFeature", "active": true, "params": [{ "name": "nbDaysLimit", "value": 3 }, { "name": "extraParamDHA", "value": "DHA" }, { "name": "extraParamDHB", "value": "DHB" } ] }, { "id": "MissingDayKeyFeature", "active": false, "params": [{ "name": "nbIntakesLimit", "value": 0 }, { "name": "extraParamMDA", "value": "MDA" }, { "name": "extraParamMDB", "value": "MDB" } ] } ]
我使用一个简单的Test
脚本来输出值,看看是否所有的绑定都正确完成
import { Main } from "./Main"; var json: string = *json above*; Main.getCalculator(json).calculate();
但是我最终会遇到这个错误
Error < at _createSubRequests (D:\Projects\226RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\planning\planner.js:106:19) < at Object.plan (D:\Projects\226RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\planning\planner.js:125:5) < at D:\Projects\226RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\container\container.js:205:37 < at Container._get (D:\Projects\226RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\container\container.js:198:44) < at Container.get (D:\Projects\226RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\container\container.js:163:21) < at Function.getCalculator (D:\Projects\226RD\nodejs\phantomjs_2016_by_DM\final\transpiled\KFCalc\Main.js:9:30) < at Object.<anonymous> (D:\Projects\226RD\nodejs\phantomjs_2016_by_DM\final\transpiled\KFCalc\Test.js:4:13) < at Module._compile (module.js:573:32) < at Object.Module._extensions..js (module.js:582:10) < at Module.load (module.js:490:32)
对于发生的事情没有任何线索,我弄不清楚我做错了什么。 我不能get<Calculator>
也没有get<KeyFeature>
,但是如果我这样做:
container.isBound(TYPES.Calculator) // returns true !!!
同样适用于所有的绑定项目。
谢谢你的指点,我没有想法。
+-- @types/node@7.0.2 +-- inversify@3.0.0 +-- reflect-metadata@0.1.9 +-- typescript@2.0.10
编辑:忘记了KeyFeatureCalculator
@injectable() export class KeyFeatureCalculator implements Calculator { // multi-injection of bound key features private _keyFeatureCalculators: KeyFeature[] = []; public constructor(@multiInject(TYPES.KeyFeature) keyFeatureCalculators: KeyFeature[]) { this._keyFeatureCalculators = keyFeatureCalculators; } public calculate(): void { console.log("calculate() at KeyFeatureCalculator"); for (var calculator of this._keyFeatureCalculators) { calculator.init(); calculator.calculate(); calculator.finish(); } } }
此外,所有我的文件(或几乎)导入inject, injectable
inversify
,还导入reflect-metadata
错误解决:对于那些没注意的人来说,每个KeyFeature
对象的属性都被注入了,它们的types是number
或者any
types。 由于这些值是从我的JSON
中检索的,所以它们被键入为any
,因此编译器不会警告绑定bind(xxx).to(yyy)
需要成为一个newable
元素!
所以,在我的例子中, yyy
就像3
,这是一个数字,因此是不可限制的。 我改变bind(xxx).toConstantValue(yyy)
,一切正常!