Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 5 —-asp.net MVC+Extjs

來源:互聯網
上載者:User

     在前面的系列中,我們已經完成了資料庫設計,資料訪問和商務邏輯,接下來我們來完成前台MVC和Extjs介面部分.

     在這段時間裡,spring.net已經發布了1.2版本,asp.net mvc也更新到了RC1 Refresh.nhibernate更新到了2.0.整個Demo程式也做了相應的更新.

     整個架構由asp.net mvc把背景業務和前台介面聯絡起來,在Controller中調用商務邏輯完成前台的調用,完成相應的視圖轉寄等工作.這樣存在兩個問題:
   Controller怎麼調用商務邏輯?    
     最好不要直接調用商務邏輯對象,按照面向介面的編程原則,這裡採用IOC依賴注入功能,把實際的業務對象注入到Controller中,這樣在Controller中只是對於業務介面編程,而與具體的實現無關.如果二次開發有修改,只需要把相應的商務邏輯實現添加進來,然後修改設定檔即可.
  Controller中是不是直接使用nhibernate的實體物件?
     nhibernate的實體物件中包含很多複雜的一對多,多對多等映射關係,這種關係很容易造成遞迴調用,而且很多屬性只是為了編程性添加的,而不需要其它層的開發人員知道.而且nhibernate的複雜實體物件在序列化時也並不容易,經常會造成循環參考,如果採用了Lazy Loading還可能會造成Session關閉的問題.
     所以在這裡引入了DTO(Data Transfer Object),用來完成和後台業務對象的相互轉換.由於採用Extjs用戶端,所以前台使用Json對象,這樣就要完成Json和DTO的相互轉換,再完成DTO和Nhibernate實體的相互轉換.
 

        下面我們就以使用者User為例,我們來完成控制層部分.

    1.DTO
         首先是DTO,很簡單,這裡我們只包括需要和前台互動的屬性,而且DTO不僅可以充當MVC中的Model,還可以用在WCF中的dataContract.
             

namespace DirectCenter.DTO{    [DataContract]   public   class UserDTO    {        [DataMember] public string UserID;        [DataMember] public string UserName;        [DataMember] public string ManagerID;        [DataMember] public string ManagerName;        [DataMember] public string DepartmentID;        [DataMember] public string DepartmentName;        [DataMember] public string CompanyID;        [DataMember] public string CompanyName;        [DataMember] public DateTime? ValidFrom;        [DataMember] public DateTime? ValidTo;        [DataMember] public string Telephone;        [DataMember]  public string Mobile;        [DataMember] public string Email;    }}

     可以看到DTO中和原來NHibernate實體屬性不一致.那他們兩個之間怎麼進行轉換呢?如果每次需要轉換時都去寫入程式碼利用性差了點,如果利用反射寫個協助類來完成相應的轉換靈活性差了點.所以又引入了DTOMapper來完成DTO和實體的轉換.可以對於Nhibernate實體中的Department,Company這樣的對象屬性,怎麼能夠通過DTOMapper轉換呢??你可以在DTOMapper中注入相應業務Manager來完成,不過那樣過於複雜了.
 
這樣我們把所有的要用到的商務邏輯介面放到AllManagerFactory中,再通過spring.net注入具體的實現,這樣在任何地方擷取執行個體是都能夠擷取到商務邏輯執行個體.
依賴注入如下:

    <object id="ManagerFactory" type="DirectCenter.DTO.AllManagerFactory,DirectCenter.DTO">              <property name="UserManager" ref="UserManagerTrans"/>           <property name="CompanyManager" ref="CompanyManagerTrans"/>             <property name="DepartmentManager" ref="DepartmentManagerTrans"/>     </object>

在AllManagerFactory中可以直接從ApplicationContext中擷取到對象:

  public static  AllManagerFactory ManagerFactory        {            get            {                var webApplicationContext =                             ContextRegistry.GetContext() as WebApplicationContext;                AllManagerFactory manager =                    webApplicationContext.GetObject("ManagerFactory") as AllManagerFactory;                return manager;            }        }

     這樣我們就可以直接在UserDTOMapper中完成DTO和nhibernate對象的相互轉換,不過感覺還是太複雜,寫入程式碼太多.

 public class UserDTOMapper:BaseDTOMapper    {        public static UserDTO MapToDTO(User  model )        {            UserDTO dto = new UserDTO();            dto.UserID = model.UserID;            dto.UserName = model.UserName;            dto.ManagerID = model.Manager == null ? "" : model.Manager.UserID;            dto.ManagerName = model.Manager == null ? "" : model.Manager.UserName;            dto.Mobile = model.Mobile;            dto.Telephone = model.Telephone;            dto.ValidFrom = model.ValidFrom;            dto.ValidTo = model.ValidTo;            dto.CompanyID = model.Company == null ? "" : model.Company.CompanyID;            dto.CompanyName = model.Company == null ? "" : model.Company.FullName;            dto.DepartmentID = model.Department == null ? "" : model.Department.DepartmentID;            dto.DepartmentName = model.Department == null ? "" : model.Department.DepartmentName;            dto.Email = model.Email;            return dto;        }        public static User MapFromDTO(UserDTO dto)        {            User user = new User();            user.UserID = dto.UserID;            user.UserName = dto.UserName;            user.Manager = dto.ManagerID == null?null:ManagerFactory.UserManager.GetUser(dto.ManagerID);            user.Mobile = dto.Mobile;            user.Telephone = dto.Telephone;            user.ValidFrom = dto.ValidFrom;            user.ValidTo = dto.ValidTo;            user.Company = dto.CompanyID == null?null:ManagerFactory.CompanyManager.GetCompany(dto.CompanyID);            user.Department = dto.DepartmentID == null? null:ManagerFactory.DepartmentManager.GetDepartment(dto.DepartmentID);            user.Email = dto.Email;            user.CreateTime = DateTime.Now;            return user;        }    }

2. Controller

       這裡我使用MvcContrib,使Asp.net Mvc運行在Spring.net容器中(MvcContrib裡面還包含StructureMap, Windsor,NVelocity等對Asp.net Mvc的支援).這樣的話,我們必須在Spring.net定義Controller對象.

 <object id="UserController"   singleton="false" type="DirectCenter.Controllers.UserController, DirectCenter.Controllers" > </object>

       注意這裡的singleton如果不設定成false的話,會由spring.net容器管理Controller,這樣只存在一個執行個體,mvc的ControllerContext在每次請求時會不清空,導致於ModelBinder在綁定Controller參數時實際上綁定的是上次請求的同名參數的值.
同DTO一樣,我們定義一個BaseController基類,在基類中加入AllManagerFactory,這樣每個繼承的Controller都可以直接使用業務介面.
比如使用者登陸,我們就可以如下實現:(UserController.cs)

    [AcceptVerbs(HttpVerbs.Post)]        public  ActionResult  Login(string userid, string password)        {            var rdto = new ResultDTO();            User  user  = ManagerFactory.UserManager.GetUser(userid);            if (user != null && user.Password.Trim() == password.Trim())            {                rdto.Message = "登陸成功";                rdto.Result = true;            }            else            {                rdto.Message = "登陸失敗";                rdto.Result = false;            }            return this.Json(rdto);        }

       MVC相關的東西在這裡就不多解釋了,新添的JsonResult方便了返回Json格式的操作.可以看到返回的是ResultDTO對象,而不是簡單的字串,這是為了規範傳回值,因為通常情況下,前台不僅需要傳回值,在其它情況下,前台需要知道執行結果以及提示資訊.ResultDTO就包括這執行結果,返回資料,提示資訊這三個屬性:

    [DataContract]    public class ResultDTO    {           [DataMember]        public bool Result;        [DataMember]        public string Message;        [DataMember]        public object Data;    }

這樣的話,前台就可以根據ResultDTO.Result屬性判斷執行,True則讀取Data,False則顯示Message
先到這裡,回家吃飯了,過會再發剩下的一篇.先發出完整的代碼下載.


作者:孤獨俠客(似水流年)
出處:http://lonely7345.cnblogs.com
本文著作權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文串連,否則保留追究法律責任的權利。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.