ASP.NET MVC+EF框架+EasyUI實現權限管系列 (開篇) (1)框架搭建 (2):數據庫訪問層的設計Demo
前言:這篇博客在數據訪問層的基礎上面我們繼續學習對這個Demo的開發,希望大家都好好理解一下這個Demo的架構,到最后我實現權限的時候我就簡單的說一下搭建過程就OK了,因為這個Demo的思想就是按照權限的設計方式去設計的,下面我們開始介紹面向接口的編程思想,如果感覺好的話可以點一下支持,下面我們切入正題。
1.新建面向接口編程的類庫
(1)在這篇博客中我們主要針對面向接口進行編程,既然是面向接口,那么我們就必須要在創建一個存放接口的類庫,然后創建幾個接口,下面我就詳細的講述一下創建這個接口類庫和接口類的過程。
(2)首先我們在這個項目下面創建數據庫訪問接口層的一個類庫,起名為:LYZJ.UserLimitMVC.IDAL,然后我們創建三個接口類,依此是:IBaseRepository.cs,IUserInfoRepository,IRoleRepository。我只是這樣說的話可能有些人會感覺雲里霧里的,所以我這里就將項目的圖形放在上面,方便大家理解,如圖所示:
(3)下面我們詳細來分析LYZJ.UserLimitMVC.IDAL類庫下面的三個接口類所實現的功能。
2. LYZJ.UserLimitMVC.IDAL類庫中三個接口類的分析
(1)IBaseRepository,在這個基接口中我們封裝了所有操作數據庫的方法,從另外一種角度來看接口的話接口就是一個約束,我們定義接口約束了操作數據庫的方法,下面因為每個數據庫實體(UserInfo,RoleInfo)都需要操作數據庫的接口,所以我定義了一個基接口用來實現對數據庫的訪問方法的封裝,然后數據庫實體只需要繼承自這個基接口即可,代碼如下:
1 public interface IBaseRepository<T> where T : class, new() 2 3 { 4 5 // 實現對數據庫的添加功能,添加實現EF框架的引用 6 7 T AddEntity(T entity); 8 10 11 //實現對數據庫的修改功能 12 13 bool UpdateEntity(T entity); 14 15 16 17 //實現對數據庫的刪除功能 18 19 bool DeleteEntity(T entity); 20 21 22 23 //實現對數據庫的查詢 --簡單查詢 24 25 IQueryable<T> LoadEntities(Func<T, bool> whereLambda); 26 27 28 29 /// <summary> 30 31 /// 實現對數據的分頁查詢 32 33 /// </summary> 34 35 /// <typeparam name="S">按照某個類進行排序</typeparam> 36 37 /// <param name="pageIndex">當前第幾頁</param> 38 39 /// <param name="pageSize">一頁顯示多少條數據</param> 40 41 /// <param name="total">總條數</param> 42 43 /// <param name="whereLambda">取得排序的條件</param> 44 45 /// <param name="isAsc">如何排序,根據倒敘還是升序</param> 46 47 /// <param name="orderByLambda">根據那個字段進行排序</param> 48 49 /// <returns></returns> 50 51 IQueryable<T> LoadPageEntities<S>(int pageIndex, int pageSize, out int total, Func<T, bool> whereLambda,bool isAsc, Func<T, S> orderByLambda); 52 53 }
(2)IUserInfoRepository,這個接口只需要實現繼承自基接口即可,當繼承基接口的時候就實現了基接口中的所有方法,代碼如下:
1 public interface IUserInfoRepository:IBaseRepository<UserInfo> 3 { 4 5 }
(3)IRoleRepository,和第(2)個解釋一樣,代碼如下:
1 public interface IRoleRepository:IBaseRepository<Role> 2 3 { 4 5 }
(4)注意:當我們操作IUserInfoRepository和IRoleRepository的時候我們需要添加LYZJ.UserLimitMVC.Model的引用,因為我們要用到數據庫實體對象。
3.數據庫訪問層的重新設計(LYZJ.UserLimitMVC.DAL類庫)
(1)角色倉儲(RoleRepository)的設計
當我們完成數據訪問接口層的時候,這時候我們就要重新修改數據庫訪問層的數據,因為要用到數據庫訪問接口層,所以我們要添加數據庫接口層的DLL,LYZJ.UserLimitMVC.IDAL。
然后我們的角色倉儲要繼承數據庫訪問接口層的角色倉儲接口,代碼如下:
1 public class RoleRepository : BaseRepository<Role>, IRoleRepository 2 3 { 4 5 }
(2)用戶倉儲(RoleRepository)的設計,和上面的解釋一樣,代碼如下:
1 public class UserInfoRepository : BaseRepository<UserInfo>, IUserInfoRepository 2 3 { 4 5 }
(3)數據庫訪問層的設計思路是:先繼承基類,在實現接口。上面的實現正是引用了這句話來實現。
注解:數據庫訪問層我們就說到這里了,如果大家有什么不懂的或者不知道的,可以給我留言,我將在第一時間回復,下面我們開始研究業務邏輯層的實現
4.業務邏輯層(BLL)初探
(1)從開始到現在我們的數據庫訪問層只能說是暫時告一段路了,因為在后面我們還會修改數據庫訪問層,我們現在寫的代碼並不是一直不變的,而是隨着寫慢慢的我們就會提取出來很多東西進行封裝,所以如果你仔細看我博客的話我一直在修改這些代碼。
(2)業務邏輯層是什么呢?我相信如果做過asp.net三層架構的用戶都是理解的,就是對數據庫訪問層的封裝,在這里我也不詳細的解釋什么是業務邏輯層了,如果大家不太理解的話可以去百度或者谷歌搜索一下。
(3)下面我們對業務邏輯層開始進行操作
5.業務邏輯層(LYZJ.UserLimitMVC.BLL)的實現
(1)首先我們新建一個UserInfoService類,這個類就是對UserInfo的業務邏輯進行實現(增刪改查)。
(2)如果我們要實現業務邏輯層的話,我們就要添加數據庫訪問層和實體層以及操作Entity FrameWork框架的的DLL,如下:LYZJ.UserLimitMVC.DAL,LYZJ.UserLimitMVC.IDAL,LYZJ.UserLimitMVC.Model,System.Data.Entity。
6.UserInfo業務邏輯類的實現
(1)首先我貼出UserInfo.cs類的代碼,在這里我們要仔細的分析一下UserInfo類的代碼的實現:
1 namespace LYZJ.UserLimitMVC.BLL 2 3 { 4 5 /// <summary> 6 7 /// UserInfo業務邏輯 8 9 /// </summary> 10 11 public class UserInfoService 12 13 { 14 15 //訪問DAL實現CRUD 16 17 //private DAL.UserInfoRepository _userInfoRepository = new UserInfoRepository(); 18 19 private IUserInfoRepository _userInfoRepository = new UserInfoRepository(); 20 21 22 public UserInfo AddUserInfo(UserInfo userInfo) 23 24 { 25 26 return _userInfoRepository.AddEntity(userInfo); 27 28 } 29 30 31 public bool UpdateUserInfo(UserInfo userInfo) 32 33 { 34 35 return _userInfoRepository.UpdateEntity(userInfo); 36 37 } 38 39 } 40 41 }
(2)因為我們的業務邏輯層要用到實體對象,也就是UserInfo,所以這里我們需要添加引用,這個我再上面已經提到過了。業務邏輯層就是去訪問數據庫訪問層(DAL),然后實現對數據庫的增刪改查,所以我們就需要定義一個數據庫訪問層的實例:private DAL.UserInfoRepository _ userInfoRepository=new UserInfoRepository();但是如果我們這樣做的話就完全的違背了我們說的依賴接口編程,所以我們不建議這么寫,既然我們已經有了接口了,那么我們可以依賴接口定義:private IUserInfoRepository _ userInfoRepository=new UserInfoRepository();,那么這兩種寫法的差別在哪里呢?它們有什么差別呢?下來我大致的說一下:
(3)上面兩種定義的區別在哪里
上面這兩種寫法,可能有的人會認為沒有區別,其實不然,這里這樣寫的區別很大,如果我們在下面有很多方法的話,我們所有的方法都要去調用倉儲里面的方法,而這個倉儲卻是接口實例,跟具體的實現就沒有什么關系,也就是說我們業務邏輯層依賴的數據訪問層的接口,只要接口不變化,那么下面的代碼都是不會變化的,如果某一天我們需要用ADO來實現這個功能的話,我們只需要替換掉new后面的UserInfo倉儲,換成ADO.NET實現的倉儲,這樣的話我們下面的方法都是不需要變化的,這就是所謂的依賴接口編程。只要接口不變化,那么我們下面的代碼永遠不會變化。
7.不想new UserInfoRepository();倉儲,怎么辦?
(1)通過上面我們定義接口來實例化對象已經使用了依賴接口的編程,但是現在我還不想new UserInfoRepository();實例,因為這個對象極有可能變化,有可能使用EF實現的倉儲,有可能使用ADO實現的倉儲,而且我們設計到業務邏輯層的實例都要定義倉儲對象,那么當我們實體很多的時候,維護起來非常的不方便,我們需要每個頁面的去修改這些東西,所以在這里我們就能夠想着使用一種什么方法將這個倉儲做為一種參數傳遞進去,而我們只需要在傳遞參數的類里面進行維護,下面我們就分析一下如何使用。
(2)遇到變化點,我們就要想辦法看能不能封裝起來,這里當然可以了,我們將獲取此倉儲實例的方法放到一個公共的地方,改變的時候直接改變這個公共的地方就行了, 那么這里怎么弄呢?我們首先想到的最簡單的就是簡單工廠,那么什么是簡單工廠呢?其實很簡單,我們只要理解只要是工廠,就是為我們創建實例的類,既然我們這里需要一個公共的地方,那么我們就要在LYZJ.UserLimitMVC.DAL這個類庫下面添加一個RepositoryFactory類,這個類里面我們建立了一個UserInfoRepository屬性,這個靜態屬性里面就是為我們返回這個倉儲即可。那么這時候如果我們想要修改的話就直接去改變UserInfoRepository屬性即可
(3) RepositoryFactory類的實現
(1)同我們上面的分析,下面我們實現這個類的代碼,代碼如下:
1 namespace LYZJ.UserLimitMVC.DAL 2 3 { 4 5 public static class RepositoryFactory 6 7 { 8 9 public static IUserInfoRepository UserInfoRepository 10 11 { 12 13 get { return new UserInfoRepository(); } 14 15 } 16 17 } 18 19 }
(2)然后我們修改業務邏輯層的定義實例化倉儲的代碼如下:
private IUserInfoRepository _userInfoRepository = RepositoryFactory.UserInfoRepository;
(3)這時候我們就完成了這個倉儲的封裝,現在我們如果想要替換倉儲的話,我們只需要去替換RepositoryFactory中的方法即可,這也就是一個簡單的簡單工廠,當我們添加上這個簡單工廠之后,我們數據庫訪問層和業務邏輯層之間的依賴就更加的減少了耦合度。
8.小結
(1)到這里這篇博客終於完事了,現在我才知道針對着項目寫博客真心不好寫,語言組織沒有寫技術點那么方便,導致我這篇文章寫了5個小時,不過功夫不負有心人,終於完事了,相比大家看得時候會比較難懂,如果大家有什么不懂的可以問我,我將這篇博客的代碼上傳到CSDN中,大家可以去下載一邊看代碼一邊看博客,我想這樣大家容易理解。
(2)下面是今天寫完這篇博客之后現在的項目架構
(3) 依賴接口編程圖紙
源碼下載
(1):完整源碼下載
Kencery返回本系列開篇