(转)一步一步Asp.Net MVC系列_权限管理设计起始篇
原文地址:http://www.cnblogs.com/mysweet/archive/2012/07/26/2610793.html
?
?
前一段時間,寫了一步一步asp.net的一系列博客,最近,也快要大四,忙著準備找個工作,這也算是最后一個假期了,這個系列可能不太長,盡量寫完.還是多學(xué)習(xí),少扯淡的風(fēng)格,我們的學(xué)習(xí)還好
繼續(xù),現(xiàn)在開始學(xué)習(xí)asp.net MVC系列,基礎(chǔ)知識,大家看博客園相關(guān)的一系列就可以了,我們在
這里學(xué)一下一個權(quán)限管理的設(shè)計.我采用的是Asp.net MVC+EF+N層的方式,順便加入點
spring.net注入的部分,當(dāng)然我們最主要的還是關(guān)于權(quán)限設(shè)計的部分.而架構(gòu),咱也沒學(xué)過太復(fù)
雜的架構(gòu),我們還是從最常用的三層架構(gòu)進行擴展.
參考書籍:
<<重構(gòu),改善既有代碼的設(shè)計>>
? <<.net應(yīng)用架構(gòu)設(shè)計原則,模式與實踐>>
<<.net設(shè)計范式>>
<<代碼整潔之道>>
? 以及網(wǎng)上眾多的教程,博客等等
首先,我們要講解一下關(guān)于項目的搭建部分.我們的項目主要分為5部分,業(yè)務(wù)邏輯層,數(shù)據(jù)訪問層,界面層,領(lǐng)域模型層以及
一個公共類的部分.
當(dāng)然,我們要先建立一個工程,并建立相應(yīng)的解決方案文件夾,并且保持清晰程度,我們在工程加上前綴(最好是公司前綴)后面加上部分.
然后在每個解決方案文件夾下面建立響應(yīng)的項目,
這里主要是:
業(yè)務(wù)邏輯層:
TZHSWEET.IBLL:業(yè)務(wù)邏輯層接口
TZHSWEET.BLL:業(yè)務(wù)邏輯層實現(xiàn)
數(shù)據(jù)訪問層:
TZHSWEET.IDao:數(shù)據(jù)訪問層接口
TZHSWEET.Dao:數(shù)據(jù)訪問層實現(xiàn)
領(lǐng)域模型層:
TZHSWEET.Entity:這是EF建立的模型
TZHSWEET.ViewModel:這個是用來傳遞UI層和業(yè)務(wù)邏輯層的相關(guān)模型對象
界面層:
TZHSWEET.WebUI:主要的MVC和LigerUI實現(xiàn)的界面部分
TZHSWEET.UI:關(guān)于MVC公共UI定義的部分
公共類庫部分:
TZHSWEET.CacheStorage主要是常用的緩存
TZHSWEET.Common主要是一些公共類實現(xiàn)等等
這里僅僅是三層架構(gòu)按照我自己的想法做了一個適應(yīng)性擴展,呵呵.
EF不用說了,這里只是一個簡單的應(yīng)用
在這里我先講解關(guān)于Idao和Dao部分
我們的目標(biāo)是"0"增刪改查的數(shù)據(jù)訪問層實現(xiàn),
主要是靠EF的定義通用的增刪改查,然后其他類繼承增刪改查接口和相應(yīng)的自定義子類接口,實現(xiàn)擴展.
首先,我們從以前寫代碼的經(jīng)驗知道,我們的Dao主要是做增刪改查等方面,我們就先定義一個公共的接口,叫做IBaseDao,這個接口定義泛型的增刪改查,
1: /* 作者: tianzh 2: * 創(chuàng)建時間: 2012/7/16 11:01:34 3: * 4: */ 5: using System; 6: using System.Collections.Generic; 7: using System.Linq; 8: using System.Text; 9: using System.Data.Objects; 10: 11: namespace TZHSWEET.IDao 12: { 13: public interface IBaseDao<T>// where T:class //限制class 14: { 15: #region 查詢普通實現(xiàn)方案(基于Lambda表達式的Where查詢) 16: /// <summary> 17: /// 獲取所有Entity 18: /// </summary> 19: /// <param name="exp">Lambda條件的where</param> 20: /// <returns></returns> 21: IEnumerable<T> GetEntities(Func<T, bool> exp); 22: 23: /// <summary> 24: /// 計算總個數(shù)(分頁) 25: /// </summary> 26: /// <param name="exp">Lambda條件的where</param> 27: /// <returns></returns> 28: int GetEntitiesCount(Func<T, bool> exp); 29: 30: /// <summary> 31: /// 分頁查詢(Linq分頁方式) 32: /// </summary> 33: /// <param name="pageNumber">當(dāng)前頁</param> 34: /// <param name="pageSize">頁碼</param> 35: /// <param name="orderName">lambda排序名稱</param> 36: /// <param name="sortOrder">排序(升序or降序)</param> 37: /// <param name="exp">lambda查詢條件where</param> 38: /// <returns></returns> 39: IEnumerable<T> GetEntitiesForPaging(int pageNumber, int pageSize, Func<T, string> orderName, string sortOrder, Func<T, bool> exp); 40: 41: /// <summary> 42: /// 根據(jù)條件查找 43: /// </summary> 44: /// <param name="exp">lambda查詢條件where</param> 45: /// <returns></returns> 46: T GetEntity(Func<T, bool> exp); 47: 48: #endregion 49: #region 查詢Sql語句外接接口的查詢實現(xiàn) 50: /// <summary> 51: /// 獲取所有Entity(立即執(zhí)行請使用ToList() 52: /// </summary> 53: /// <param name="CommandText">Sql語句</param> 54: /// <param name="objParams">可變參數(shù)</param> 55: /// <returns></returns> 56: IEnumerable<T> GetEntities(string CommandText); 57: 58: /// <summary> 59: /// 計算總個數(shù)(分頁) 60: /// </summary> 61: /// <param name="CommandText">Sql語句</param> 62: /// <param name="objParams">可變參數(shù)</param> 63: /// <returns></returns> 64: int GetEntitiesCount(string CommandText); 65: 66: /// <summary> 67: /// 分頁查詢(Linq分頁方式) 68: /// </summary> 69: /// <param name="tableName">表名</param> 70: /// <param name="pageNumber">當(dāng)前頁</param> 71: /// <param name="pageSize">頁碼</param> 72: /// <param name="orderName">lambda排序名稱</param> 73: /// <param name="sortOrder">排序(升序or降序)</param> 74: /// <param name="CommandText">Sql語句</param> 75: /// <param name="Count">總個數(shù)</param> 76: /// <returns></returns> 77: IEnumerable<T> GetEntitiesForPaging(string tableName, int pageNumber, int pageSize, string orderName, string sortOrder, string CommandText, out int Count); 78: 79: /// <summary> 80: /// 根據(jù)條件查找 81: /// </summary> 82: /// <param name="CommandText">Sql語句</param> 83: /// <param name="objParams">可變參數(shù)</param> 84: /// <returns></returns> 85: T GetEntity(string CommandText); 86: 87: #endregion 88: /// <summary> 89: /// 插入Entity 90: /// </summary> 91: /// <param name="model"></param> 92: /// <returns></returns> 93: bool Insert(T entity); 94: /// <summary> 95: /// 更新Entity 96: /// </summary> 97: /// <param name="model"></param> 98: /// <returns></returns> 99: bool Update(T entity); 100: /// <summary> 101: /// 刪除Entity 102: /// </summary> 103: /// <param name="entity"></param> 104: /// <returns></returns> 105: bool Delete(T entity); 106: } 107: }接下來,我們需要定義一系列的接口繼承這個接口,代碼類似:
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using TZHSWEET.Entity; 6: 7: namespace TZHSWEET.IDao 8: { 9: 10: public interface IDepartmentDao<T> : IBaseDao<T> where T : class 11: { 12: 13: } 14: }這層接口,大家可能認為沒什么必要,但是,這個接口非常重要,這個接口保證了我們用EF一個抽象類實現(xiàn)增刪改查的同時又增加了子類的自身擴展性.
接下來,就是Dao部分,我們需要很慎重的去設(shè)計,
首先我們要設(shè)計一個用EF實現(xiàn)的公共父類的BaseEFDao類,用他來實現(xiàn)增刪改查,
1: /* 作者: tianzh 2: * 創(chuàng)建時間: 2012/7/16 11:06:16 3: * 4: */ 5: using System; 6: using System.Collections.Generic; 7: using System.Linq; 8: using System.Text; 9: using TZHSWEET.IDao; 10: using TZHSWEET.Entity; 11: using System.Data; 12: using TZHSWEET.Common; 13: using System.Data.Objects; 14: namespace TZHSWEET.EFDao 15: { 16: /// <summary> 17: /// 公共接口 18: /// </summary> 19: public class BaseEFDao<T> : IBaseDao<T> where T : class,new() //限制T為class 20: { 21: 22: #region 查詢普通實現(xiàn)方案(基于Lambda表達式的Where查詢) 23: /// <summary> 24: /// 獲取所有Entity 25: /// </summary> 26: /// <param name="exp">Lambda條件的where</param> 27: /// <returns></returns> 28: public virtual IEnumerable<T> GetEntities(Func<T, bool> exp) 29: { 30: 31: using (BaseManageEntities Entities = new BaseManageEntities()) 32: { 33: return Entities.CreateObjectSet<T>().Where(exp).ToList(); 34: } 35: 36: } 37: /// <summary> 38: /// 計算總個數(shù)(分頁) 39: /// </summary> 40: /// <param name="exp">Lambda條件的where</param> 41: /// <returns></returns> 42: public virtual int GetEntitiesCount(Func<T, bool> exp) 43: { 44: using (BaseManageEntities Entities = new BaseManageEntities()) 45: { 46: return Entities.CreateObjectSet<T>().Where(exp).Count(); 47: } 48: } 49: /// <summary> 50: /// 分頁查詢(Linq分頁方式) 51: /// </summary> 52: /// <param name="pageNumber">當(dāng)前頁</param> 53: /// <param name="pageSize">頁碼</param> 54: /// <param name="orderName">lambda排序名稱</param> 55: /// <param name="sortOrder">排序(升序or降序)</param> 56: /// <param name="exp">lambda查詢條件where</param> 57: /// <returns></returns> 58: public virtual IEnumerable<T> GetEntitiesForPaging(int pageNumber, int pageSize, Func<T, string> orderName, string sortOrder, Func<T, bool> exp) 59: { 60: using (BaseManageEntities Entities = new BaseManageEntities()) 61: { 62: if (sortOrder=="asc") //升序排列 63: { 64: return Entities.CreateObjectSet<T>().Where(exp).OrderBy(orderName).Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList(); 65: } 66: else 67: return Entities.CreateObjectSet<T>().Where(exp).OrderByDescending(orderName).Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList(); 68: } 69: 70: } 71: /// <summary> 72: /// 根據(jù)條件查找 73: /// </summary> 74: /// <param name="exp">lambda查詢條件where</param> 75: /// <returns></returns> 76: public virtual T GetEntity(Func<T, bool> exp) 77: { 78: using (BaseManageEntities Entities = new BaseManageEntities()) 79: { 80: return Entities.CreateObjectSet<T>().Where(exp).SingleOrDefault(); 81: } 82: } 83: #endregion 84: #region 查詢Entity To Sql語句外接接口的查詢實現(xiàn) 85: /// <summary> 86: /// 獲取所有Entity(立即執(zhí)行請使用ToList() 87: /// </summary> 88: /// <param name="CommandText">Sql語句</param> 89: /// <param name="objParams">可變參數(shù)</param> 90: /// <returns></returns> 91: public virtual IEnumerable<T> GetEntities(string CommandText) 92: { 93: 94: using (BaseManageEntities Entities = new BaseManageEntities()) 95: { 96: return Entities.ExecuteStoreQuery<T>("select * from "+typeof(T).Name+" where "+CommandText).ToList(); 97: } 98: 99: } 100: /// <summary> 101: /// 計算總個數(shù)(分頁) 102: /// </summary> 103: /// <param name="CommandText">Sql語句</param> 104: /// <returns></returns> 105: public virtual int GetEntitiesCount(string CommandText) 106: { 107: using (BaseManageEntities Entities = new BaseManageEntities()) 108: { 109: return Entities.ExecuteStoreQuery<T>("select * from " +typeof(T).Name+ " where "+CommandText).Count(); 110: } 111: } 112: 113: /// <summary> 114: /// 分頁查詢(Linq分頁方式) 115: /// </summary> 116: /// <param name="tableName">表名</param> 117: /// <param name="pageNumber">當(dāng)前頁</param> 118: /// <param name="pageSize">頁碼</param> 119: /// <param name="orderName">lambda排序名稱</param> 120: /// <param name="sortOrder">排序(升序or降序)</param> 121: /// <param name="CommandText">Sql語句</param> 122: /// <param name="Count">總個數(shù)</param> 123: /// <returns></returns> 124: public virtual IEnumerable<T> GetEntitiesForPaging(string tableName, int pageNumber, int pageSize, string orderName, string sortOrder, string CommandText,out int Count) 125: { 126: PaginationHelper pager = new PaginationHelper(tableName, orderName, pageSize, pageNumber, sortOrder, CommandText); 127: pager.GetSelectTopByMaxOrMinPagination(); 128: using (BaseManageEntities Entities = new BaseManageEntities()) 129: { 130: Count =GetEntitiesCount(CommandText); 131: return Entities.ExecuteStoreQuery<T>(pager.GetSelectTopByMaxOrMinPagination()).ToList(); 132: 133: } 134: 135: } 136: /// <summary> 137: /// 根據(jù)條件查找 138: /// </summary> 139: /// <param name="CommandText">Sql語句</param> 140: /// <param name="objParams">可變參數(shù)</param> 141: /// <returns></returns> 142: public virtual T GetEntity(string CommandText) 143: { 144: using (BaseManageEntities Entities = new BaseManageEntities()) 145: { 146: return Entities.ExecuteStoreQuery<T>("select * from "+typeof(T).Name+" where "+CommandText).SingleOrDefault(); 147: } 148: } 149: #endregion 150: #region 增刪改實現(xiàn) 151: /// <summary> 152: /// 插入Entity 153: /// </summary> 154: /// <param name="model"></param> 155: /// <returns></returns> 156: public virtual bool Insert(T entity) 157: { 158: using (BaseManageEntities Entities = new BaseManageEntities()) 159: { 160: var obj = Entities.CreateObjectSet<T>(); 161: obj.AddObject(entity); 162: return Entities.SaveChanges() > 0; 163: } 164: } 165: /// <summary> 166: /// 更新Entity(注意這里使用的傻瓜式更新,可能性能略低) 167: /// </summary> 168: /// <param name="model"></param> 169: /// <returns></returns> 170: public virtual bool Update(T entity) 171: { 172: using (BaseManageEntities Entities = new BaseManageEntities()) 173: { 174: var obj = Entities.CreateObjectSet<T>(); 175: obj.Attach(entity); 176: Entities.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified); 177: return Entities.SaveChanges() > 0; 178: } 179: 180: } 181: /// <summary> 182: /// 刪除Entity 183: /// </summary> 184: /// <param name="entity"></param> 185: /// <returns></returns> 186: public virtual bool Delete(T entity) 187: { 188: using (BaseManageEntities Entities = new BaseManageEntities()) 189: { 190: var obj = Entities.CreateObjectSet<T>(); 191: 192: if (entity != null) 193: { 194: obj.Attach(entity); 195: Entities.ObjectStateManager.ChangeObjectState(entity, EntityState.Deleted); 196: 197: obj.DeleteObject(entity); 198: return Entities.SaveChanges() > 0; 199: 200: } 201: return false; 202: } 203: } 204: 205: #endregion 206: 207: 208: 209: } 210: }
接下來我們的工作量就小了,我們可以看到成果了,我們接下來的實現(xiàn),只需要繼承上面這個BaseEFDao和IxxxDao的部分就可以很輕松的實現(xiàn),子類的增刪改查以及子類的擴展了.
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using TZHSWEET.Entity; 6: using TZHSWEET.IDao; 7: namespace TZHSWEET.EFDao 8: { 9: public class FavoriteEFDao : BaseEFDao<tbFavorite>, IFavoriteDao<tbFavorite> 10: { 11: 12: } 13: }大家可以看到繼承了2個,一個是BaseEFDao父類,一個是IFavoriteDao接口,
BaseEFDao是實現(xiàn)EF的增刪改查,IFavoriteDao實現(xiàn)了子類的擴展,比如子類需要加入
GetxxxByID之類的,當(dāng)然我們在業(yè)務(wù)邏輯層一般只能通過IFavoriteDao調(diào)用此服務(wù),而
這個繼承體系保證了我們在實現(xiàn)增刪改查的同時外放一個接口保證擴展性.
繼承體系圖:
這樣我們的數(shù)據(jù)訪問層,很輕松的實現(xiàn)了,基本上代碼量非常少,增刪改查部分幾乎"0"代碼,都是泛型的父類實現(xiàn)了.
今天就講解到這里,接下來插播點當(dāng)前有趣的實例部分:
界面友好,友好的名稱遠遠比注釋更好,<<重構(gòu)>>這本書,讓我學(xué)到太多太多,特別是細節(jié)的設(shè)計,更清晰.
可以參考,我的代碼風(fēng)格,可以看到我的進步非常大,我現(xiàn)在看到2-3個月以前的代碼,簡直都是<<重構(gòu)>>這本書的反面教材.
當(dāng)前的權(quán)限管理系統(tǒng),設(shè)計了一個初步的模型,這里貼張小圖:
參考了LigerUI,謝略的權(quán)限管理系統(tǒng),吉日的權(quán)限管理數(shù)據(jù)庫設(shè)計和N多日志,以及傳說中的弦哥的Asp.Net大型項目實踐系列教程,以及眾多的資料,慢慢的我也會把這個寫成一個系列.最后,寫完這個教程,我會把代碼傳到公共網(wǎng)盤上面,不過由于現(xiàn)在代碼持續(xù)改進,所以,就大家先看看思路.
一直在努力,從未曾放棄,努力學(xué)習(xí)中.....歡迎一起學(xué)習(xí).net!
轉(zhuǎn)載于:https://www.cnblogs.com/fcsh820/archive/2012/08/10/2632280.html
總結(jié)
以上是生活随笔為你收集整理的(转)一步一步Asp.Net MVC系列_权限管理设计起始篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XT910开通了GPRS却上不了网的原因
- 下一篇: 第四次游戏革命:全息游戏 from:ht