在上一篇,介紹了如何處理檔案上傳的部分。但是,裡面處理上傳檔案的邏輯是放在Mvc的Action裡面。
這個有一些壞處,首先,和邏輯相關的不應該寫在Controller裡面,因為Controller的工作很簡單,就只是決定Model的資料,和顯示的View是哪一個。把處理這種邏輯放在Controller裡面破會了所謂的關注點分離(SoC)的概念。
再來屬於SoC的衍生,因為如果邏輯寫在了Controller裡面,未來如果要替換邏輯或者需要做一些測試的時候,更本不好做。加上,如果別的地方也需要同樣邏輯的時候,更本沒有辦法通用。
因此,這一篇將會介紹如何把邏輯抽到Service層裡面。
功能概述
基本的邏輯在上一篇實作了在Controller裡面,現在要抽到Service裡面,尤其是通用型的Service(也就是GenericService<T>),就要以能夠動態的角度去思考如何處理這部分的邏輯,因此,定下一些規則。如果進來的ViewModel符合這些規則,就處理,要不然就不處理。
檔案處理的邏輯如果在仔細思考一下,基本上就是:
- 把
HttpPostedFileBase
檔案儲存 (在有檔案的情況下) - 把儲存檔案的路徑放到要儲存到DB的欄位
如果要把上面的邏輯自動化的話,就變成:
- 找到這個ViewModel裡面是不是有
HttpPostedFileBase
- 並且裡面有檔案 - 把檔案儲存
- 把路勁給要存到DB的欄位即可 - 要如何知道是哪一個欄位?
關於第三點,就是這個框架處理要設定的規則,有符合規則就處理,要不然就不處理。
規則
HttpPostedFileBase
這個欄位的名字是實際存到DB的欄位名字加上File
。
舉例來說,如果實際存到DB的欄位名字是:CoverImg
,那麼對應的HttpPostedFileBase
名字就是CoverImgFile
有了這個規則,就可以把檔案上傳的部分移動到Service裡面。
功能實作
接下來就看看如何實際實作功能。
在Service裡面新增ViewModel的部分
上面,highlight起來就是會處理檔案上傳的部分。
這個方法基本上就是透過Reflection來找到HttpPostedFileBase
,並且找到對應的檔案。如果有,就會做處理:
Controller的變化
把處理的部分移到Service之後,在Controller裡面就變成原來的樣子:
結語
透過Service層,可以把一些通用的邏輯抽進去,避免掉Controller有太多邏輯,造成日後邏輯無法替換和重複使用。
在接下來還會介紹更多Service還能夠包括的功能,使得這些底層的內容還需要每一次都處理。