昨天我們依然使用 ViewModel 來對 View 客製化顯示與傳值,但在 Controller 取值的部分,Code 好像可以再更簡潔一點,也可以再降一點耦合程度。
今天會介紹並使用 Repository Pattern 這一個 Design Pattern,讓 Controller 不直接耦合 EF Core 且將取值的 Function 抽出來,降低 Code 重複程度。
Repository 意指儲存庫,通常我們取資料時,理想上只想要看到 Function 名稱是甚麼,就去呼叫,並且回傳自己想要的值。這段話和昨天的 Code 是不是有點對不上呢?
可以發現,我們呼叫 Function,腦中只想著呼叫後即可取得資料,不必知道資料是怎麼來的,這就和我們目前的 Code 衝突了。
從 Code 可以看到,需要 Events/EventsInfo 的資料,就從 EF Core 取資料,這會發生一些問題:
導入 Repository Pattern 就是在解決以上問題,我們解除對 EF Core 的強耦合外,也能降低重工的部分,也降低開發時間並更加直覺,直接看 Function 就知道會取得甚麼資料。
介面可以規範後續繼承的 Class 該實作哪些 Function,可以當作一個規格,未來要擴充 Function 時,每一個繼承該 Interface 的 Class 就都需要實作規範的 Function,不會有漏掉的情況發生:
先簡單列出基本的 CRUD 功能,並且建立一個新的 EventsRepository.cs
,加入繼承 IEventsRepository 後,可直接使用 intellisense 來自動產生該實作的 Function:
以昨天的 Events 活動列表頁取值為例,先實作 GetEvents()
來試試:
其實就是把原本在 Controller 撈資料的 Code,搬移到這裡。
如此就完成了 Repository GetEvents()
的實作,接下來我們要讓服務啟動時,納入 DI 注入的目標服務中。
用 Scoped 的模式,DI 看到 IEventsRepository
的介面時,會注入 EventsRepository
這一個類別。
Controller 一樣也需要在建構子加上 Repository,讓 DI 可以注入:
在 Index
這個 Action,將原本的 Code 都移除掉,並加上呼叫 EventsRepository
的 Function,然後再將從 Repository 取得的 Events
放到 EventsListViewModel
內,再將 ViewModel 放到 View 內,如此就完成了。
如此 Action 就不會對 EF Core 直接耦合,其實就可以將 appDbContext 從 Controller 拿掉了。
功能還是正常運作!
在今天,我們導入 Repository,並將 Controller 與 EF Core 的強耦合解開,也讓呼叫取資料的 Function 可以被重複使用,大大的讓 Code 的重複性降低,並減少 Code 的數量。
明天將會展示導入 Repository 與 DI 的好處,讓我們可以在測試資料或是正式資料之間切換,並且不會影響到服務的穩定性。
那麼我們明天見。
Design the infrastructure persistence layer
用Repository Pattern抽離對Entity Framework的依賴