使用RequireJS进行依赖注入

Aar*_*ius 35 javascript requirejs

我可以伸展RequireJS为我的应用程序提供依赖注入多少?举个例子,假设我有一个我希望成为单身人士的模特.自执行getInstance()中不是单例 - 类型单例,而是上下文强制单例(每个"上下文"一个实例).我想做点什么......

require(['mymodel'], function(mymodel) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

并让mymodel成为MyModel类的一个实例.如果我要在多个模块中执行此操作,我希望mymodel是相同的共享实例.

我已经通过制作mymodel模块成功完成了这项工作:

define(function() {
    var MyModel = function() {
        this.value = 10;
    }
    return new MyModel();
});
Run Code Online (Sandbox Code Playgroud)

这种用法是预期和常见的还是我滥用RequireJS?有没有更合适的方法可以使用RequireJS执行依赖注入?谢谢你的帮助.仍在努力抓住这一点.

Dom*_*nic 60

这实际上不是依赖注入,而是服务位置:您的其他模块通过字符串"key"请求"类",并获取"服务定位器"(在本例中为RequireJS)已连接到的实例提供给他们.

依赖注入将涉及返回MyModel构造函数,即return MyModel,然后在中心组合根中将实例注入MyModel到其他实例中.我在这里汇总了一个如何工作的样本:https ://gist.github.com/1274607 (也在下面引用)

通过这种方式,组合根确定是否MyModel为每个需要它的实例(实例作用域)或其间的某个类分发单个实例(即使其成为单例作用域)或新实例.该逻辑既不属于MyModel的定义,也不属于要求其实例的类.

(旁注:尽管我没有使用它,但wire.js是一个成熟的JavaScript依赖注入容器,看起来非常酷.)


你不一定像你一样使用它来滥用RequireJS,虽然你正在做的事似乎有点迂回,即声明一个类而不是返回它的新实例.为什么不做以下事情呢?

define(function () {
    var value = 10;

    return {
        doStuff: function () {
            alert(value);
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

您可能缺少的类比是模块在大多数其他语言中等同于"命名空间",尽管您可以将函数和值附加到命名空间.(因此更像Python而不是Java或C#.)它们不等同于类,尽管如您所示,您可以使模块的导出等于给定类实例的导出.

因此,您可以通过将函数和值直接附加到模块来创建单例,但这有点像使用静态类创建单例:它非常不灵活,通常不是最佳实践.但是,大多数人都把它们的模块视为"静态类",因为正确构建一个依赖注入系统需要从一开始就考虑很多,这在JavaScript中并不是真正的常态.


这里是https://gist.github.com/1274607内联:

// EntryPoint.js
define(function () {
    return function EntryPoint(model1, model2) {
        // stuff
    };
});

// Model1.js
define(function () {
    return function Model1() {
        // stuff
    };
});

// Model2.js
define(function () {
    return function Model2(helper) {
        // stuff
    };
});

// Helper.js
define(function () {
    return function Helper() {
        // stuff
    };
});

// composition root, probably your main module
define(function (require) {
    var EntryPoint = require("./EntryPoint");
    var Model1 = require("./Model1");
    var Model2 = require("./Model2");
    var Helper = require("./Helper");

    var entryPoint = new EntryPoint(new Model1(), new Model2(new Helper()));
    entryPoint.start();
});
Run Code Online (Sandbox Code Playgroud)