简体   繁体   English

节点依赖性容器无法按预期工作

[英]Node dependency container doesn't work as expected

I have a DI container like this: 我有一个像这样的DI容器:

# di-container.js
const container = {
    fileReader: require("./file-reader"),
    csvReader: require("./csv-reader"),
}

module.exports = {
    container
}

And csv-reader.js looks like this: csv-reader.js看起来像这样:

# csv-reader.js
const { container } = require("./di-container")

async function readFileAsCSV(path)
    const fileContents = await container.fileReader.readFileContents(path)
    return fileContents.split("\n")
                       .map(line => line.split(","))
}

I have a test file csv-reader.spec.js : 我有一个测试文件csv-reader.spec.js

# csv-reader.spec.js
const { container } = require("./di-container")

describe("csvReader", () => {
    it("should read cells from file", async () => {
        const fakeCSV = "\"Name\",\"Age\"\n\"Bob Smith\",\"32\""
        container.fileReader.readFileContents = (_) => fakeCSV

        const result = container.csvReader.readFileAsCSV()

        # Do some assertions...
    })
})

When running the test it fails with the error (stack trace line numbers different as the example is slightly different): 运行测试时,它会因错误而失败(堆栈跟踪行号不同,因为示例略有不同):

TypeError: Cannot read property 'fileReader' of undefined
 at Object.readFileAsCSV (csv-reader.js:8:42)
 at Context.it (csv-reader.spec.js:15:44)
 at processImmediate (internal/timers.js:443:21)

I expected that the memory reference to container is the same in csv-reader.spec.js and csv-reader.js , so I should be able to change container.fileReader.readFileContents and csv-reader will use the mock function. 我期望在csv-reader.spec.jscsv-reader.jscontainer的内存引用是相同的,所以我应该能够更改container.fileReader.readFileContentscsv-reader将使用mock函数。

If I remove the csvReader: require("./csv-reader") line from di-container.js and use const csvReader = require("./csv-reader") in csv-reader.spec.js , then the test passes. 如果我从di-container.js删除csvReader: require("./csv-reader")行并在csv-reader.spec.js使用const csvReader = require("./csv-reader") ,那么测试经过。 This would suggest some oddity with the order in which the dependencies in container are being created. 这表明在创建container中的依赖项的顺序方面存在一些奇怪之处。

I have tried rearranging the order of fileReader and csvReader in container , and changing them to be like container.fileReader = ... instead of inline instantiation but that did not work.jav 我已经尝试重新排列containerfileReadercsvReader的顺序,并将它们更改为像container.fileReader = ...而不是内联实例化但是没有工作.jav

You have a dependency module cycle . 您有一个依赖模块循环

Your di-container.js file requires csv-reader.js and csv-reader.js file requires di-container.js which forms a cycle. 你的di-container.js文件需要csv-reader.jscsv-reader.js文件需要di-container.js来形成一个循环。

Because of this, require("./di-container") returns null inside the csv-reader.js file. 因此, require("./di-container")csv-reader.js文件中返回null Because require("./di-container") is null , The destructured container will be undefined. 因为require("./di-container")null ,所以destructured container将是未定义的。 And thus, your are getting the error which you mentioned. 因此,你得到了你提到的错误。

You need to redesign your functions and might want to think about where do you want to put them. 您需要重新设计您的功能,并可能想要考虑您希望将它们放在何处。


On very broad level, just separate out the functions which are to be used in both the files and put them inside common.js 在非常广泛的层面上,只需将两个文件中使用的函数分开并将它们放在common.js

Then, require common.js inside csv-reader.js and di-container.js 然后,在csv-reader.jsdi-container.js common.js


If I remove the csvReader: require("./csv-reader") line from di-container.js and use const csvReader = require("./csv-reader") in csv-reader.spec.js, then the test passes. 如果我从di-container.js中删除csvReader:require(“./ csv-reader”)行并在csv-reader.spec.js中使用const csvReader = require(“./ csv-reader”),那么测试经过。 This would suggest some oddity with the order in which the dependencies in container are being created. 这表明在创建容器中的依赖项的顺序方面存在一些奇怪之处。

The cycle broke once you did not require csv-reader.js from the di-container.js and hence it is working just fine. 一旦你不需要来自di-container.js csv-reader.js破坏循环,因此它工作得很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM