依賴注入似乎已經成為許多軟體框架的必要元素,它的概念仍然不易被人熟悉,但其方便性以及能夠帶給軟體開發的彈性是很大很大的。 Soma.js 是 javascript 的一個以 infuse.js 為基底開發的依賴注入程式框架(framework),依循它所提供的規則,可以自動偵測到建構式所需要的參數,使用 this 定義的物件變數,Soma.js 將在所有註冊在它身上的變數中,尋找相同名字的變數置入。
換言之⋯ 只要取相同的名字, Soma.js 能夠自動完成變數對應的工作。很方便,但也是其限制。要是一旦名字不同了呢?要是不同時期開發出來的程式,用了同一個名稱表示不同的名字呢? Soma.js 的對應機制是不是就無法順利運作了?
另一個會改變名字的地方在於程式的最小化,為了極致地減少程式碼所佔用的空間,會以較短的文字(像單一字母)取代變數名稱。如此處理的程式碼,很有可能會使得依賴注入失效。
同樣的情形也出現在同為 javascript 的 AngularJS 框架中,而 AngularJS 的處理方式,是在建立 controller, service 的地方,以陣列取代原先傳入建構函數的地方。陣列中列舉了每個注入引用的名稱,最後一個陣列元素才是建構式。由於程式最小化不會對字串進行處理,因此可以避免注入的對應出錯。
那麼回到 Soma.js 身上,它使用了 injector.createInstance 方法來建立物件,然而只接受一個參數,也只能是建構函數。它是支援在建構函數後頭增加其它的參數,依序作為建構函數的參數,不足的部分的由既有的注入對應機制處理、補齊。
不過,如果傳入的參數是要注入項目的名稱,會發現該名稱的字串,會直接作為參數傳入建構函數,而不是該名稱所對應的物件。因此,如果要傳入注入名稱的對應,不能使用 injector.createInstance 函數來達到。
最後的由其的基底 infuse.js 的文件中找到,它的作法是在建構函數上定義 inject 變數,其對應到建構時所注入物件名稱,經過實測的結果是能夠順利運作。至於物件內的變數要怎麼對應,這個部分就留待未來有需要再進行測試。
以下列個簡單的物件宣告⋯ (注意 inject 是定義給建構函數,而不是建構出來的物件上)
function MyClass(opt1, opt2) {
// some code...
}
MyClass.inject = ['optName', 'otherOption'];
module.exports = MyClass;