架構,改善程(cheng)序復(fu)用性的設計~第六講 我(wo)的系統(tong)結構~將所有(you)可以(yi)抽象的項目進行(xing)抽象(大結局)
N層架構及各層之間(jian)的通訊(xun)標準
一 總體結構圖
二 各個模塊的介紹
通用項(xiang)目(mu)(mu)模塊(kuai)Project.Common:它(ta)是對所有項(xiang)目(mu)(mu)都公(gong)開的(de)項(xiang)目(mu)(mu)組合,主要提供一個與領域(yu)無關的(de)通用功能的(de)代(dai)碼(ma)庫
核心項目模(mo)塊Project.Core:它是針(zhen)對(dui)某種構架方式(shi)(如LINQ To SQL作為底(di)層(ceng)架構)抽象出來的項目組(zu)合,它與(yu)領域無關
領(ling)域(yu)項(xiang)(xiang)目(mu)模塊,它是(shi)具體的(de)(de)項(xiang)(xiang)目(mu),如XXB項(xiang)(xiang)目(mu),它本(ben)身也是(shi)一個N層架構方式,一般地(di),它的(de)(de)UI層會繼承我(wo)們的(de)(de)Product.Core下的(de)(de)Web.Commons項(xiang)(xiang)目(mu),而(er)對應的(de)(de)Entity對應Entity.Commons項(xiang)(xiang)目(mu),由(you)于BLL層是(shi)針對某種特(te)殊業務領(ling)域(yu)的(de)(de),所(suo)以(yi)在(zai)Project.Core里(li)沒(mei)有出現BLL層的(de)(de)抽象。
以下是一個Demo項(xiang)目的結構
三 具體領域模塊各層之(zhi)間(jian)的通訊(xun)標(biao)準
由于(yu) project.common和project.core是(shi)(shi)(shi)比較穩定的(de)(de),而且對所(suo)有解決方案(an)都是(shi)(shi)(shi)共用的(de)(de),所(suo)以(yi)在這(zhe)里(li)它不(bu)是(shi)(shi)(shi)我們討(tao)論的(de)(de)重點,我們主要說(shuo)一(yi)下具體領域模塊(kuai)的(de)(de)各層間的(de)(de)通(tong)訊問題
領域模塊總體圖:
3.1 UI層與BLL層通訊
添加(jia)刪(shan)除(chu)與更新操作統(tong)(tong)一(yi)使用(yong)實體類型,如(ru)果(guo)要返回(hui)信(xin)息(xi),請使用(yong)統(tong)(tong)一(yi)的(de)消息(xi)類
1 /// <summary> 2 /// 插入商品 3 /// </summary> 4 VMessage AddProduct(Product entity);
而(er)查詢使用(yong)(yong)統一使用(yong)(yong)一個(ge)字典類型來存(cun)儲(chu)條件,用(yong)(yong)一個(ge)結構體存(cun)儲(chu)分頁參(can)數
1 /// <summary> 2 /// 根據條件得到分頁結(jie)果集 3 /// </summary> 4 /// <param name="vp"></param> 5 /// <param name="pp"></param> 6 /// <returns></returns> 7 PagedList<Product> GetProduct(VPredication vp, PagingParam pp);
3.2 BLL層與DAL層通(tong)訊(xun)
BLL層將數(shu)據(ju)(ju)(ju)進行組(zu)合后,調用(yong)數(shu)據(ju)(ju)(ju)層統(tong)一的(de)(de)方法即可,數(shu)據(ju)(ju)(ju)層只提供最基礎的(de)(de)GURD操作,涉及到多表插入,查詢的(de)(de),統(tong)一在BLL層進行組(zu)合實(shi)現。
下面(mian)是業務層代碼的實現:
1 /// <summary> 2 /// 商(shang)品(pin)模(mo)塊實現 3 /// </summary> 4 public class ProductService : ServiceBase, IProductService 5 { 6 IProductRepository iProductRepository = null; 7 public ProductService() 8 { 9 iProductRepository = new ProductRepository(); 10 } 11 12 #region IProductService 成¨|員?à 13 public Entity.VMessage AddProduct(Entity.Car_Rental.Product entity) 14 { 15 try 16 { 17 iProductRepository.Insert(entity); 18 VMessage.IsComplete = true; 19 } 20 catch (Exception) 21 { 22 // throw; //發布后注釋它¨1 23 VMessage.IsComplete = false; 24 } 25 return VMessage; 26 } 27 public Entity.PagedList<Entity.Car_Rental.Product> GetProduct(Entity.VPredication vp, Entity.PagingParam pp) 28 { 29 var linq = iProductRepository.GetDetailModel(); 30 return new Entity.PagedList<Entity.Car_Rental.Product>(linq, pp.PageIndex, pp.PageSize); 31 } 32 #endregion 33 }
四 實體驗證機制
應該是一(yi)種前臺特殊效果驗(yan)(yan)證(zheng)和實(shi)體有效性(xing)驗(yan)(yan)證(zheng)相結合(he)的一(yi)種驗(yan)(yan)證(zheng)方式,前臺驗(yan)(yan)證(zheng)一(yi)般指JS驗(yan)(yan)證(zheng),可(ke)能產生(sheng)一(yi)些(xie)用戶體驗(yan)(yan)比較(jiao)好的效果,實(shi)體驗(yan)(yan)證(zheng)多在(zai)實(shi)體層完成,在(zai)進行添加,修改等操作時,需要進行些(xie)驗(yan)(yan)證(zheng)。
4.1 實體統(tong)一基類(lei):
在EntityBase類中已(yi)經完成(cheng)了對實(shi)體(ti)非(fei)空的驗(yan)(yan)(yan)證(zheng)(zheng),GetRuleViolations方(fang)法(fa)將返(fan)回驗(yan)(yan)(yan)證(zheng)(zheng)失(shi)敗的迭代結果(guo)集(ji),它(ta)是一(yi)個(ge)虛方(fang)法(fa),子類可以根據自己的邏輯去復寫它(ta)。IsValid是一(yi)個(ge)屬性,它(ta)在判斷(duan)實(shi)體(ti)驗(yan)(yan)(yan)證(zheng)(zheng)時(shi)被賦值(zhi),為true表示成(cheng)功,反之,驗(yan)(yan)(yan)證(zheng)(zheng)失(shi)敗。
對于復合實(shi)(shi)體,如(ru)在前臺表單(dan)中可以(yi)出現多個(ge)實(shi)(shi)體組(zu)合的(de)情況,這(zhe)時,可以(yi)使(shi)用(yong)MVC的(de)那種方法,頁面(mian)元(yuan)素寫在一個(ge)ViewModel里,供這(zhe)個(ge)頁面(mian)視(shi)圖(tu)使(shi)用(yong),使(shi)用(yong).net的(de)attribute 很(hen)容易的(de)可以(yi)實(shi)(shi)現屬性(xing)的(de)驗(yan)證。
在(zai)(zai)controller層(ceng)(可(ke)能根(gen)據(ju)業務需(xu)要(yao),也(ye)會被抽象(xiang)出來),我(wo)們在(zai)(zai)進行實(shi)體添加與修(xiu)改(gai)操(cao)作時,需(xu)要(yao)判斷實(shi)體的IsValid,然后(hou)再去調用(yong)BLL層(ceng)的方(fang)法,一般代碼是(shi)這(zhe)樣:
1 [HttpPost] 2 public ActionResult Create(FormCollection collection) 3 { 4 News entity = new News(); 5 TryUpdateModel(entity); 6 entity.CreateDate = DateTime.Now; 7 entity.UpdateDate = DateTime.Now; 8 entity.Status = (int)Status.Normal; 9 if (entity.IsValid) 10 { 11 iNewsRepository.Insert(entity); 12 return AlertToUrl("Index"); 13 } 14 else 15 { 16 entity.GetRuleViolations().ToList().ForEach(i => 17 { 18 ModelState.AddModelError(i.PropertyName, i.ErrorMessage); //驗證沒有通過(guo)的信息 19 }); 20 } 21 return View(); 22 }
五 接口的重要性
接口可能會成功我們(men)的累贅,添加了代碼量,(F12)轉到(dao)定義時也會帶來不(bu)方便,我們(men)是(shi)否應該(gai)廢棄接口
它的好處:
1 統一,穩定的操作規范
2 使用接口,配和IOC,實(shi)現(xian)一(yi)種(zhong)操作的多種(zhong)實(shi)現(xian)方式的切(qie)換
對DAL層接口與(yu)實現的(de)抽(chou)象圖(tu)示