首頁 >web前端 >js教程 >JavaScript 依賴注入實現

JavaScript 依賴注入實現

黄舟
黄舟原創
2017-02-21 11:53:181796瀏覽



隨著AngularJS的流行,依賴注入開始在JavaScript領域獲得不少的關注。 DI最突出的好處在於開發可重複使用可測試的程式碼單元。 本文以簡易的程式碼解釋DI的實作機制,更多DI優缺點的討論可參考: 何時應該使用依賴注入 一文。

一個基本的DI用例

每個模組宣告自己的依賴,並提供自己的服務。例如:

di.service('foo', ['bar'], function foo(bar){ function Foo(){ this.bar = bar;
    } this.prototype.greeting = function(){ console.log('hello, world');
    } return Foo;
}); var foo = di.container.get('foo');
foo.greeting();

注意依賴注入和CommonJS(或AMD)的區別, foo 只需要宣告其依賴項 bar 而不需要主動取得。 正是這一點使得 function foo 對依賴所處的位置和建置方法都完全無知, function foo 成為可測試、可重複使用的程式碼單元。

DI框架的設計

註冊服務和使用服務應該在不同時期進行。 作為一種特殊的依賴解決工具,DI框架將軟體單元的生命週期分為註冊階段和運行階段。 在上述範例中,在註冊階段提供 foo 和 bar 服務,在運作階段取得並使用這些服務。 多數DI框架都採取lazy construction的策略,該策略也避免了在註冊階段進行建構的困難。

服務的客製化可以在註冊階段後運行階段前進行。 AngularJS 1 引入配置階段來客製化這些服務,其Provider可以理解為一個特化的工廠物件。 BottleJS 則使用修飾器和中介軟體來支援對服務的客製化。

使用IoC容器來索引服務實例或儲存服務提供者。 當有人提供服務時就把它加入容器中, 當有人使用服務時就從容器中尋找提供者並產生一個服務實例。 通常服務的實例可以被快取。

DI框架的實作

先來實作最常見的介面函數 .service() ,該介面用來註冊一個服務的建構器。 被傳入的函數將會被進行 new 操作。

var di = {
    container: {}
};

di.service = function(name, Constructor) {
    defineLazyProperty(name, () => new Constructor());
}; function defineLazyProperty(name, getter){ Object.defineProperty(di.container, name, {
        configurable: true,
        get: function() { var obj = getter(container); Object.defineProperty(di.container, name, {
                configurable: false value: obj
            }); return obj;
        }
    });
}

Object.defineProperty 在這裡用來做服務快取。 只在第一次建置服務時呼叫構造器,後續的存取就是直接讀取IoC容器的屬性。 它是ES5的標準方法 相容性非常好 。 有了defineLazyProperty() 方法,這些常用的註冊介面實作就很直觀了:

di.factory = function(name, factory) { return defineLazyProperty(name, factory);
};

di.provider = function(name, Provider) { return defineLazyProperty(name, function(){ var provider = new Provider(); return provider.$get();
    });
};

di.value = function(name, val) { return defineLazyProperty(name, () => val);
};

服務的客製化介面就不再贅述了,值得一提的是統一的服務客製化需要統一的服務建構方法, 而不是直接呼叫.defineLazyProperty() 生成屬性。 AngularJS 中這些策略都由Provider來實現, 其他的所有服務註冊方法都藉由Provider來實現。

 

以上就是JavaScript 依賴注入實現的內容,更多相關內容請關注PHP中文網(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn