DIP 依賴反轉原則 Dependency Inversion Principle 的定義如下:
高級別的模塊不應該依賴於低級別的模塊, 他們都應該依賴於抽象.
假設Controller依賴於Repository的實例/實現, 而不是interface:
這個例子里面Controller是高級別模塊, Repository是低級別模塊.
但是根據定義: 高級別的模塊不應該依賴於低級別的模塊, 他們都應該依賴於抽象. 那么如何解決這個問題呢?
那就是 從Repository中提煉出一個interface, 叫做IRepository, 它就是個抽象:
這樣一來, Controller依賴於IRepository, 所以高級別模塊不依賴於低級別模塊, 他們現在都依賴於抽象了.
那么這么做有什么好處? 為什么要使用DIP原則?
答案就是: 減少變化帶來的影響.
看第一張圖:
就從一個方面來說, 如果Repository被重新編譯了, 那么Controller肯定需要重新編譯, 也就是所有依賴於Repository的類都會被重新編譯.
而使用DIP原則之后:
我們可以在Repository里面做出很多更改, 但是這些變化都不會影響到Controller, 因為Controller並不是依賴於這個實現.
只要IRepository這個interface或者叫Contract合約不發生變化, Controller就不會被影響到. 這也就可能會較少對整個項目的影響.
Interface 代表的是 "是什么樣的", 而實現代表的是 "如何去實現".
Interface一旦完成后是很少改變的.
針對使用Repository+UnitOfWork模式的asp.net core的項目結構, 少許碼友可能會有一點錯誤的理解, 可能會把asp.net core項目的結構這樣划分:
這樣一來, 其實就是這樣的:
高級別的包/模塊依賴於低級別的包/模塊.
也就違反了DIP原則, 所以如果想按原則執行, 就需要引進一個新的模塊:
把所有的抽象相關的類都放在Core里面.
這樣就滿足了DIP原則.
asp.net core的項目結構大致應該是這個思路:
由於Models是整個項目的核心內容, 所以也放在了Core里面.
當然也可以分成多個項目去實現DIP, 但是不一定按多個項目分開了就一定實現了DIP, 還是要看他們之間的依賴關系.