NodeJS

时间:2017-06-18 08:03:53

标签: javascript node.js dependency-injection

最近,我开始涉足nodeJS。

现在我知道依赖注入是解决代码并将其保持整齐的模式。

但是,当您有一个使用其他依赖项的依赖项时,您会怎么做?

例如,假设我有一个使用数据库模块和用户模块的投资模块,用户模块也使用数据库模块。 假设我有一个使用投资模块,数据库模块和用户模块的提款模块。在模块的对象中定义属性并在整个应用程序中将其他依赖项注入其中是否明智?

const dbc = require('./dbc');
const user = require('./user');
const invest = require('./invest');
const withdraw = require('./withdraw');

let user.dbc = dbc;
let invest.user = user;
let invest.dbc = dbc;
let withdraw.invest = invest;
let withdraw.user = user;
let withdraw.dbc = dbc;

这是最好/最聪明的方法吗?这件事情有些不对劲。 当然,我可以将数据库模块注入用户模块并将用户模块注入投资模块,并将投资模块注入提取模块。但是这件事情也不干净。

如果有人应该向我展示亮点,那么社区就会接受这种做法的标准做法,那就太好了。

2 个答案:

答案 0 :(得分:0)

要求模块多次使用绝对没问题。 NodeJS只执行一次模块中的代码,并记住模块导出的内容。

当您第二次需要该模块时,模块不会再次执行(并且不会创建另一个数据库连接)。相反,require('./dbc')的结果将始终是对表示数据库连接的同一对象的引用。

答案 1 :(得分:0)

内置的NodeJS依赖注入对我来说还不够。原因如下:

  1. 它自然没有组件生命周期管理,即Singleton,Transient和Wrapped。假设您想在上下文中将模块用作单例,而在另一个上下文中使用瞬态,则必须处理为模块创建使用两种不同的工厂方法。
  2. 通过' require()'向模块主体注入依赖关系不建议使用中央依赖管理。此外,它很难解决循环依赖,尽管这个问题很少发生。
  3. 那些激励我为NodeJS应用找到更好的DI。那里有很多人。我还为自己写了一个轻量级的DI。如果您认为有帮助,可以尝试一下:https://github.com/robo-creative/nodejs-robo-container

    借助DI的支持,我能够坚持将每个模块声明为一种类型,而不再是它们的工厂方法。模块生命周期将由容器管理。您的代码如下所示:

    var $ = require('robo-container');
    
    // dbc should only be a type, we can restrict it to have only one instance.
    $.bind('dbc').to(require('./dbc')).asSingleton();
    
    // following statements use Property Injection
    // user should be a type that may have multiple instances (transient).
    $.bind('user').to(require('./user')).set({ dbc: 'dbc' });
    
    // invest and withdraw should be types.
    $.bind('invest').to(require('./invest')).set({ user: 'user', dbc: 'dbc' });
    $.bind('withdraw').to(require('./withdraw')).set({ user: 'user', dbc: 'dbc', invest: 'invest' });
    

    上面的绑定语句使用Property Injection。如果你“撤回”#39; module有一个接受user,dbc和invest的构造函数,你可以像这样使用Constructor Injection:

    // the withdraw module.
    function WithdrawModule(user, dbc, invest) {
    
        this.doSomething = function() {
    
        }
    }
    
    $.bind('withdraw').to(require('./withdraw')).use('user', 'dbc', 'invest');
    

    要创建撤销实例,请调用$()或$ .resolve():

    var withdraw = $('withdraw'); // or $.resolve('withdraw');
    withdraw.doSomething();
    

    那就是它。希望你能回答你的问题。