InversifyJS:从容器中检索对象时出错

InversifyJS : Error when retrieving object from container

我正在使用 InversifyJS 设置某种动态绑定,运行 它在 NodeJS 上。我遇到的问题是出现错误,但没有消息,只有堆栈跟踪。

Mainclass

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;
        }
    }
}

此 class 使用 json 字符串调用 KeyFeatureContainer,用于配置所有绑定(以某种动态方式),然后检索容器。

KeyFeatureContainerclass

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);
    }
}

此 class 接收 json 配置并在 ID 之后加载 ContainerModule,其中包含接口与具体实现之间的绑定。 rootContainer 指定 ContainerModule 在 ID 之后检索。

rootContainer

var rootContainer: Container = new Container();

rootContainer.bind<KeyFeatureContainerModule>(KEYFEATURES.DrugHoliday).to(DrugHolidayContainerModule);
rootContainer.bind<KeyFeatureContainerModule>(KEYFEATURES.MissingDay).to(MissingDayContainerModule);

export default rootContainer;

和相关的ContainerModules(第二个是相同的,只是每个参数不同)

@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 输入(为了方便格式化)

[{
        "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:\Projects6RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\planning\planner.js:106:19)
<     at Object.plan (D:\Projects6RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\planning\planner.js:125:5)
<     at D:\Projects6RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\container\container.js:205:37
<     at Container._get (D:\Projects6RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\container\container.js:198:44)
<     at Container.get (D:\Projects6RD\nodejs\phantomjs_2016_by_DM\final\node_modules\inversify\lib\container\container.js:163:21)
<     at Function.getCalculator (D:\Projects6RD\nodejs\phantomjs_2016_by_DM\final\transpiled\KFCalc\Main.js:9:30)
<     at Object.<anonymous> (D:\Projects6RD\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();
        }
    }
}

此外,我的所有文件(或几乎所有文件)都从 inversify 导入 inject, injectable 并且还导入 reflect-metadata

错误已解决:没注意的人,每个KeyFeature个对象都注入了属性,它们的类型是numberany。由于这些值是从我的 JSON 中检索到的,因此它们被键入为 any,因此编译器不会警告我绑定 bind(xxx).to(yyy) 需要是一个 newable 元素!

因此,在我的示例中,yyy 类似于 3,它是一个数字,因此不受限制。我更改为 bind(xxx).toConstantValue(yyy),一切正常!