在上一篇介紹完了如何讓ViewModel和Entity之間的轉換透過AutoMapper變的更簡單,然後透過框架讓設定ViewModel和Entity之間的對應關係變的容易。
在這一篇,將會看Data Access Layer (DAL)的部份,也就是儲存資料層的部份。
Data Acce Layer (DAL)
不管任何大小的軟體,通常都會需要儲存資料。而這個儲存資料最常見的就是儲存到資料庫裡面。以Asp .Net Mvc來說,最常見的就是透過Entity Framework這個ORM的技術來儲存到實體的資料庫,例如MS Sql,Oracle等。
而如果以Entity Framework來講,它所在的角色就屬於DAL層。
以一般比較常見的三層是架構,大概就會如下圖:
用Entity Framework做DAL的問題
其實這個問題不只有使用Entity Framework會,任何的DAL實作都有這個問題。
舉個例子來說,假設今天我們用的是Entity Framework作為DAL層,如果開發到一半,對方突然要求不要使用Entity Framework,而是要改成傳統的ADO .Net作為DAL怎麼辦?
或者說如果要做單元測試(Unit Testing),肯定不希望在跑的時候還是連資料庫,而是希望連一些假資料,這時候怎麼辦?
解決方法其實很簡單,就是把實際的DAL在抽一層出來,就有了所謂的Repository Pattern。
Repository Pattern
一般來說,在寫Mvc裡面最長看到的Pattern就是Repository Pattern。
這個Pattern概念非常簡單,Repository其實有儲存庫的意思,所以這個Pattern的意思是,把實際的DAL層透過所謂的Repository封裝之後,從外面的角度來說是和Repository 溝通來取得資料,至於Repository的資料來源是那裡,就不管了。
文字敘述可能有些抽象,我們來看一張圖:
可以看到,左邊的圖是一般直接用Entity Framework,而右邊使用了Repository Pattern + Unit of Work(下一篇介紹),因此可以再真實的環境用Entity Framework連資料庫,然後在單元測試的時候,連假資料。
這樣就可以把實際的資料來源抽象化,提供更大的彈性。
定義Repository的interface
Repository有很多種實作方法,共通的來說,1個Repository代表一個DB 裡面的 Table。通常的做法有兩種,一種是每一個Table就一個interface,另外一種是以Generic的方式,寫一種通用型的Repository。
我這邊會介紹的是通用型的Repository。
首先,一般的DB 動作有所謂的CRUD,因此我們的interface就至少會包含這幾種動作。同時,我們還會有一個SaveChanges的方法,代表把目前有記錄的動作執行。
定義好了之後,我們就來看實作。
Entity Framework的Repository interface實作
再來我們就定義一個EF版本的Repository實作:
使用Entity Framework的Repository
注入的部分
首先看一下我們如何注入Repository
進來:
Create和Read(Index)用法比對
Update和Delete用法比對
看過這幾個常見的比對,應該發現和之前(直接使用EF的Context)用法差不多,但是對未來的彈性大幅度提到,下面將舉一個簡單的例子。
模擬要做單元測試,把Repository實作抽換
因為我們的Controller會要的是IRepository
,因此當要做單元測試的時候,我們可以給另外一個實作,例如:
那做單元測試就簡單並且減少時間(不需要和DB溝通),因為資料是我們灌好的假資料,可以掌控內容。
結語
希望透過這一篇,對於爲什麽和如何使用Repository Pattern會有些概念,不過Repository本身還是有些問題。
一個DB肯定不止一個Table,而Repository只代表了一個Table,那如果我同時要用2個Table以上怎麼辦?這個時候Unit of work就進來了。
Unit of work就留到下一篇在講了。