天天看點

依賴注入(IOC)二

上一章我們講了構造注入與設值注入,這一篇我們主要講接口注入與特性注入。
接口注入是将抽象類型的入口以方法定義在一個接口中,如果客戶類型需要獲得這個方法,就需要以實作這個接口的方式完成注入。實際上接口注入有很強的侵入性,除了要求客戶類型增加前面兩種方式所需要的代碼外,還必須顯示地定義一個新的接口并要求客戶類型實作它。
随着C#語言的發展,接口注入可以采用與設值注入方式相似的方式實作,而且看上去很“Lamada化”。因為不用真正去實作接口,而是通過泛型參數的方式實作,可以說泛型為C#實作接口注入提供了“新生”。
直覺上,客戶程式可能在使用上做出讓步以适應變化,但這違背了依賴注入的初衷,即三個角色(客戶對象、Assembler、抽象類型)之中兩個不能變,如果在Assembler和客戶類型選擇,為了客戶對象影響最小,我們隻好在Assembler上下功夫,因為它的職責是負責組裝。反過來講,如果注入過程還需要修改客戶程式,那我們就沒有必要去“削足适履”地去用“依賴注入”了。 是以,為了能通過特性方式完成依賴注入,我們隻好在Assembler上下功夫
(錯誤的實作情況) class SystemTimeAttribute:Attribute,ITimeProvider{…} [SystemTime] class Client{…} 相信讀者也發現了,這樣做雖然把客戶類型需要的ITimeProvider通過“貼标簽”的方式告訴它了,但事實上又把客戶程式與SystemTimeAttribute“綁”上了,他們緊密的耦合在一起了。參考上面的三個實作,當抽象類型與客戶對象耦合的時候我們就要用Assembler解耦。 當特性方式出現類似情況時,我們寫一個AtttibuteAssembler不就行了嗎? 還不行,設計上要把Attribute設計成一個通道,出于擴充和通用性的考慮,它本身要協助AtttibuteAssembler完成ITimeProvider的裝配,最好還可以同時裝載其他抽象類型來修飾客戶類型。

示例代碼如下