javascript - 函数式编程中的依赖注入(inject)

标签 javascript dependency-injection

这个问题最好用一个例子来说明。我将使用 Javascript(出于语法考虑,实际上是 Coffeescript),但只是因为 Javascript 只是另一个 LISP ,对吧?

因此,假设我正在编写一个执行(显然)ajax 请求的网络应用程序。我实现了一个函数来处理:

ajaxRequest = (url, params, callback) ->
    # implementation goes here

现在,假设我有一个从服务器获取数据的网格。在我的代码中的某个地方,我必须做这样的事情:

userGrid.onMustFetch = ->
    ajaxRequest '/fetch/users', { surname: 'MacGyver' }, (data) ->
        # fill grid with data

这里到底有什么问题?如果我想测试onMustFetch的实现,我是做不到的,因为在onMustFetch内部,正在调用一个依赖,测试环境无法控制依赖。

为了解决这个问题,我将依赖项注入(inject)到我要测试的函数中。这意味着将 onMustFetch 更改为:

userGrid.onMustFetch = (ajaxRequest) ->
    ajaxRequest '/fetch/users', { surname: 'MacGyver' }, (data) ->
        # fill grid with data

现在测试代码可以将 ajaxRequest 的模拟传递给 onMustFetch 并成功测试行为。

Wunderbar,对吧?错误的!现在我有第二个问题,必须将 ajaxRequest 的正确实例绑定(bind)到 onMustFetch 的正确实例。

在像 Java 这样的语言中,我可以使用依赖注入(inject)框架为我做这件事,我的代码看起来像这样:

class UserGrid {

    private AjaxService ajaxService;

    @Inject
    public UserGrid(AjaxService ajaxService) {
        this.ajaxService = ajaxService;
    }

    public void onMustFetch() {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("surname", "MacGyver");
        ajaxService.request("/fetch/users", params, new AjaxCallback(data) {
            // fill grid with data
        });
    }

}

令人毛骨悚然,我知道......但实际上 DI 框架完成了所有的连接,所以至少这部分问题更容易了。

现在回到我们的网络应用程序和 Javascript。即使我成功地设法始终使用正确的 ajaxRequest 引用调用 onMustFetch(毕竟在这种情况下这并不难做到),一定有更简单的方法。当我的代码增长时,依赖性也会增加。我可以想象传递一个 ajaxRequest 的引用,但是如果我有一个 securityService、一个 browserService、一个 eventBusService,等等,等等,等等?

现在真正的问题来了:类似 lisp 的语言如何解决管理依赖关系的问题? (在我看来,依赖项必须在整个应用程序中不断传递,但我确信必须有更好的方法...)

最佳答案

这通常是使用闭包/柯里化(Currying)来完成的。您将依赖项作为参数传递。在 JS 中你可以这样做:

buildUserGrid = function(dependency){
    return {
        onMustFetch = function(){
            depenency.doSomething();
        },
        doSomethingElse = function(){
            dependency.doSomethingElse();
        }
    }
}

var userGrid = buildUserGrid(ajaxRequest);
userGrid.onMustFetch();

关于javascript - 函数式编程中的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10197462/

相关文章:

javascript - 动态地从json中选择元素

Scala Play 测试在依赖注入(inject)期间找不到 WSClient

android - Koin依赖注入(inject)本地和远程数据源之间的切换

javascript - 何时确定一次值并将其存储在变量中,而不是重复确定它,(javascript)?

javascript - 使用 $sum 和 $cond 获取值的 $sum,而不是 mongo 中实例的总和

javascript - flowtype 似乎认为 Object.keys 输出始终是字符串数组,即使它知道得更好

javascript - "google is not defined"在 Chrome 中调用 google map api 时出错

java - 如何以编程方式创建具有注入(inject)属性的 bean 定义?

java - Spring-注入(inject)的变量为空

dependency-injection - 是否有任何简单的方法可以用 dagger2 替换 Guice 中的 DI 实现