從整潔架構談自定義 NuGet 套件規劃與使用
從整潔架構談自定義 NuGet 套件規劃與使用
前言
我們在規劃框架與底層元件時,免不了會將框架的底層元件、像是你 UI 的 BasePage、或者是 MVC 中你自定義的 ViewPage 的 BaseViewPage 又或者是你自定義框架 Framework/Platform 的底層運作包裝成 NuGet 套件供使用該功能的各系統負責人使用,將特定功能包裝成 NuGet 套件再重複使用某些功能時非常的方便,它可能方便到有種魔力,甚至會讓你想將許多功能都包裝成 NuGet 套件以達到重複使用的目的。
問題的發生
現在問題來了,這也是我在客戶端發現到的一個現象。
客戶:Entity Framework 的資料存取功能適合包成一個 NuGet 套件嗎?
這裡問題來了... 我說:請問這個是指這個套件內容會包含 OR-Mapping 的 Entites/Repository 等內容嗎?😯
如果是,那這個可能不適合包成一個 NuGet 套件。(蝦~什麼?)
客戶接著會說:但是 Entity Framework 本身也是個套件。
我說:Entity Framework 本身由套件來提供這個當然沒有問題,但是你的 Repositories/Entities 以上那已經跟商業有關了?
客戶更疑惑了:我們在開發框架時,比如說我們的 Business Object 的 Base 不是就是由 NuGet 套件提供的嗎?
我說:你說的沒有錯!但是你現在是把 DataAccess Layer 包成了 NuGet 套件了,當然~沒錯你會認為 DataAccess 算是 Infrastructure 這的確是沒錯!但是這裡的 Infrastructure 應該算是(與你的 Domain/Business 無關的部分)也就是應該不包括你的 Entities 都可以包進 NuGet,那是不正確的。
這時客戶會說,這好難界定阿?老師你說 DataAccess 就是 Infrastructure,但是又不能包進 NuGet,那到底該怎麼做啊?🙁
當時,我我很即興的繪製一個【簡圖】來說明(而現在我將這簡圖用 PowerPoint 來畫更專業點的,若想查看原本的簡圖可看我在臉書的 PO 文:https://www.facebook.com/groups/361804473860062/permalink/7962208900486210/)、我引用 Clean Architecture 的概念(對!連套件規畫概念也是一樣的、學好整潔架構 Clean Architecture 你可以想通很多問題)像是現在的套件依賴問題。
從整潔架構解釋 NuGet 套件規劃方式
(1). 以領域核心來看,你的 DB 與 Common Utility 都算是最外層
(2). ORM 功能底層由 NuGet 提供沒有問題,但是你有發現『越上層』就不適合了,從 Repository 開始就不太適合了,甚至 Repository 應該由 Code Generate 來自動產生即可,因為那是會跟著你的『商業』變動的部分,這部分是不適合包成 NuGet 套件的。
(3). 而我們的商業都是由套件底層來提供,這也是沒有問題的,我們目前就是如此做的!
結論
你頂多可以將你 ADO.NET 的資料存取 / 與商業無關的 SQL Generator/Parameters 包裝成 NuGet 套件來共用,越往上層就應該會變動的商業部份了,這部分可能用精靈來產生可能比較適合。我記得我有一個擴充套件就是拿來產生 Repositories 的。
最後
所謂的套件依賴,指的是【套件】通常包裝的是【細節】(這是整潔架構中的定義),因為 NuGet Packages 套件提供的通常是 Framework/Pltatform 也就是框架或平台等細節部分,通常是相依性的順序是框架相依 Application/Use Case 層,所以在 Application/Use Case 要使用外層的細節時應該要透過依賴反轉 DIP 來取用到外部的細節所提供的功能,那部份其實也是實作中最複雜的,在實務上有可能部分違反整潔架構的相依性原則的,那麼就看你決定哪一些套件綁定你的應用層,也就是未來的修改都會被這個套件所影響、包括測試、包括維護性等等。
留言
張貼留言