ASP.NET MVC項目框架快速搭建實戰


MVC項目搭建筆記----

 

項目框架采用ASP.NET MVC+Entity Framwork+Spring.Net等技術搭建,采用”Domain Model as View Model“的MVC開發模式,結合了抽象工廠的思想降低了三層之間的耦合,可以使用此套框架進行MVC項目的快速搭建。本框架的架構圖如下:

 

第一步(創建分類文件夾):

創建5個文件夾。分別為UI,Model,BLL,DAL,Common,以便於將各模塊分類整理。

第二步(項目類庫的創建):

在UI文件夾創建ASP.NET MVC4項目模板選擇基本。

在Model文件夾創建Model類庫項目。

在BLL文件夾創建BLL和IBLL類庫項目。

在DAL文件夾創建DAL,IDAL,DALFactory類庫項目。

在Common文件夾創建Common類庫項目。

第三步(創建EF實體):

在數據庫管理工具新建一個數據庫,在Model層添加一個ADO.Net實體模型。

建好實體模型,右鍵選擇“根據模型生成數據庫”,也可以先建好數據庫再右鍵“從數據庫更新模型”。

第四步(各層內容的創建,重點!):

在DAL層創建一個EFDbContextFactory類。(CallContext是類似於方法調用的線程本地存儲區的專用集合對象,並提供對每個邏輯執行線程都唯一的數據槽。數據槽不在其他邏線程上的調用上下文之間共享。)

 1 public class EFDbContextFactory
 2     {
 3         public static DbContext GetCurrentDbContext()
 4         {
 5             //線程內的單例:保證線程內實例唯一
 6             DbContext db = (DbContext)CallContext.GetData("DbContext");
 7             if (db == null)
 8             {
 9                 db = new Model1Container();
10 
11                 CallContext.SetData("DbContext", db);
12             }
13             return db;
14         }
15     }

在DAL層創建一個BaseDal類,作為所有Dal的基類,封裝crud方法。

 1 public class BaseDal<T> where T : class , new()
 2     {
 3         private DbContext db
 4         {
 5             get
 6             {
 7                 return EFDbContextFactory.GetCurrentDbContext();
 8             }
 9         }
10         public virtual T Add(T entity)
11         {
12             db.Set<T>().Add(entity);
13             return entity;
14         }
15 
16         public virtual bool Update(T entity)
17         {
18             db.Entry(entity).State = EntityState.Modified;
19             return true;
20         }
21 
22         public virtual bool Delete(T entity)
23         {
24             db.Entry(entity).State = EntityState.Deleted;
25             return true;
26 
27         }
28 
29         public virtual int Delete(params int[] ids)
30         {   
31             foreach (var item in ids)
32             {
33                 var entity = db.Set<T>().Find(item);//如果實體已經在內存中,那么就直接從內存拿,如果內存中跟蹤實體沒有,那么才查詢數據庫。
34                 db.Set<T>().Remove(entity);
35             }
36             return ids.Count();
37         }
38 
39         public List<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
40         {
41             return db.Set<T>().Where(whereLambda).AsQueryable();
42         }
43 
44         public List<T> LoadPageEntities<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, bool isAsc)
45         {
46             total = db.Set<T>().Where(whereLambda).Count();
47             if (isAsc)
48             {
49                 return
50                 db.Set<T>()
51                   .Where(whereLambda)
52                   .OrderBy(orderbyLambda)
53                   .Skip(pageSize * (pageIndex - 1))
54                   .Take(pageSize)
55                   .AsQueryable().ToList();
56             }
57             else
58             {
59                 return
60                db.Set<T>()
61                  .Where(whereLambda)
62                  .OrderByDescending(orderbyLambda)
63                  .Skip(pageSize * (pageIndex - 1))
64                  .Take(pageSize)
65                  .AsQueryable().ToList();
66             }
67         }
68     }
69 

 

在DAL層添加Dal類的T4模板(Dal類生成模板,生成各Dal類,包括繼承類和接口,未給出,可自行編寫)。T4模板生成的Dal類內容模板如下:

1 public partial class UserInfoDal : BaseDal<UserInfo>,IUserInfoDal
2 {
3        
4 }    

在IDAL層添加IDal接口類的T4模板(未給出,自行編寫)。T4模板生成的IDal類內容模板如下:

1 public partial interface IUserInfoDal :IBaseDal<UserInfo>
2 { 
3 
4 }    

在IDAL層添加IBaseDal接口類,作為IDal的基接口類,子接口只要繼承此接口就可以實現crud(增刪改查)及分頁接口。

1 public interface IBaseDal<T>
2 {
3         T Add(T entity);
4         bool Update(T entity);
5         bool Delete(T entity);
6         int Delete(params int[] ids);
7         List<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
8         List<T> LoadPageEntities<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, bool isAsc);
9 }

在IDAL層添加IDbSession接口類(此類作為DbSession類的約束,符合抽象的思想,不直接返回對象本身,而是返回他的接口,這樣就不會直接對對象本身造成依賴,只要修改IDbSession)的T4模板(未給出,自行編寫)。T4模板生成的IDbSession類內容模板如下:

1 public partial interface IDbSession
2 {      
3     IUserInfoDal UserInfoDal { get; }
4     int SaveChanges();
5 }    

在DALFactory層添加DbSession類的T4模板(未給出,自行編寫)。T4模板生成的DbSession類內容模板如下:

 1 public partial class DbSession :IDbSession
 2     {  
 3     
 4         private IUserInfoDal _UserInfoDal;
 5         public IUserInfoDal UserInfoDal {
 6             get {
 7                 if (_UserInfoDal == null)
 8                 {
 9                     _UserInfoDal =new UserInfoDal();
10                 }
11                 return _UserInfoDal;
12             }
13         }
14 
15         public int SaveChanges()
16         {
17             //這里只需要調用當前線程內部的上下文SaveChange。
18             DbContext dbContext = EFDbContextFactory.GetCurrentDbContext();
19             return dbContext.SaveChanges();
20         }
21     }

在DALFactory層添加DbSessionFactory類,作為dbSession的工廠。

 1 public class DbSessionFactory
 2 {
 3         public static IDbSession GetDbSession()
 4         {
 5             IDbSession dbSession = (IDbSession) CallContext.GetData("DbSession");
 6             if (dbSession == null)
 7             {
 8                 dbSession = new DbSession();
 9                 CallContext.SetData("DbSession", dbSession);
10                 return dbSession;
11             }
12             return dbSession;
13         }
14 }

在IBLL層創建IBaseService基接口類,作為所有IService接口類的crud公共約束。

 1 public interface IBaseService<T>
 2 {
 3         T Add(T entity);
 4         bool Update(T entity);
 5         bool Delete(T entity);
 6         int Delete(params int[] ids);
 7         List<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
 8 
 9         List<T> LoadPageEntities<S>(int pageSize, int pageIndex, out int total,
10                                                   Expression<Func<T, bool>> whereLambda
11                                                   , Expression<Func<T, S>> orderbyLambda, bool isAsc);
12         int Savechanges();
13 }

在IBLL層添加IBLL接口類的T4模板(未給出,自行編寫)。T4模板生成的IBLL接口類內容模板如下:

1 public  partial interface IUserInfoService :IBaseService<UserInfo>
2 {
3 
4 }

在BLL層創建BaseService類(作為所有Service類的基類,封裝crud方法)。

 1 public abstract class BaseService<T> where T:class,new ()
 2     {
 3         public IDbSession DbSession
 4         {
 5             get { return DbSessionFactory.GetDbSession(); }
 6         }
 7 
 8         public IBaseDal<T> CurrentDal;
 9 
10         public int Savechanges()
11         {
12             return DbSession.SaveChanges();
13         }
14 
15         //要求所有的業務方法在執行之前必須給當前的CurrentDal 賦值。
16         public BaseService()
17         {
18             SetCurrentDal();
19         }
20 
21         //純抽象方法:子類必須重寫此方法。
22         public abstract void SetCurrentDal();
23 
24         public virtual T Add(T entity)
25         {
26             return CurrentDal.Add(entity);
27         }
28 
29         public virtual bool Update(T entity)
30         {
31             CurrentDal.Update(entity);
32 
33             return this.Savechanges() > 0;
34         }
35 
36         public virtual bool Delete(T entity)
37         {
38             return CurrentDal.Delete(entity);
39 
40         }
41 
42         public virtual int Delete(params int[] ids)
43         {
44             return CurrentDal.Delete(ids);
45 
46         }
47 
48         public List<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
49         {
50             return CurrentDal.LoadEntities(whereLambda);
51 
52         }
53 
54         public List<T> LoadPageEntities<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, bool isAsc)
55         {
56             return CurrentDal.LoadPageEntities(pageSize, pageIndex, out total, whereLambda, orderbyLambda, isAsc);
57         }
58     }
BaseService

在BLL層添加Services類的T4模板(未給出,自行編寫)。T4模板生成的Service類內容模板如下:

1 public partial class UserInfoService:BaseService<UserInfo>,IUserInfoService
2 {
3         public override void SetCurrentDal()
4         {
5             CurrentDal = DbSession.UserInfoDal;//對父類虛方法進行重寫,以對Dal初始化。 6         }
7 }

第五步(配置Spring.Net框架):

在UI層添加lib文件夾(用於存放所有外部引用文件),將Spring.Net程序集文件夾放到lib文件夾下,UI層添加對Spring.Core,Spring.Web,Spring.Web.Extensions,Spring.Web.Mvc4程序集的引用。

在Global.asax文件里將MvcApplication類繼承至SpringMvcApplication。

在Web.config文件里的<configuration>下的<configSections>節點下添加:

1 <!--Spring配置節點-->
2     <sectionGroup name="spring">
3       <section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc4"/>
4       <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
5     </sectionGroup>
6 <!--Spring配置節點結束-->

在Web.config文件里的<configuration>節點下添加:

 1 <!--Spring配置節點-->
 2   <spring>
 3 
 4     <context>
 5       <!--選擇XML文件的位置,3種方式,1 配置文件 2 定位文件 3 程序集-->
 6       <!--<resource uri="config://spring/objects"/>-->
 7       <!--resource uri="file://ServiceXml.xml"/-->
 8       <!--resource uri="file://Controllers.xml"/-->
 9       <resource uri="assembly://MyOA_BLL/MyOA_BLL/ServiceXml.xml"/>
10       <resource uri="assembly://MyOA/MyOA/Controllers.xml"/>
11       <!--<resource uri="assembly://SpringNetTest/SpringNetTest/objects1.xml"/>-->
12     </context>
13     <objects xmlns="http://www.springframework.net">
14 
15     </objects>
16 
17   </spring>
18   <!--Spring配置節點結束-->

第六步(注入Service對象):

在BLL層添加生成ServiceXml配置文件的T4模板(Speing.Net屬性注入方法請參見  http://www.cnblogs.com/sunniest/p/4125561.html   ),內容模板為:

1 <objects xmlns="http://www.springframework.net"> 
2     <object name="UserInfoService" type="MyOA_BLL.UserInfoService, MyOA_BLL"  singleton="false">
3 
4   </object>
5   
6 </objects>

在Controller文件夾下的各Controller類中添加

1 public IUserInfoService UserInfoService{get;set;}
2 IDbSession session = DbSessionFactory.GetDbSession();

用UserInfoService來調用業務邏輯的方法(通過Spring.net注入UserInfoService對象),在操作完成后用session的savechanges方法控制將對實體的操作保存到數據庫中。

在UI層添加Controller.xml文件(用於向Controller類注入UserInfoService對象),內容模板為:

1 <objects xmlns="http://www.springframework.net">
2   <object name="TestController" type="MyOA.Controllers.TestController, MyOA"  singleton="false">
3     <property name="UserInfoService" ref="UserInfoService" />
4   </object>
5 
6 </objects>

至此項目基本框架搭建完成!

 

Controller調用業務邏輯層完整代碼示例:

 1      public ActionResult Test()
 2         {
 3             return View();
 4         }
 5 
 6         [HttpPost]
 7         public ActionResult Test(string uname,string pwd)
 8         {
 9             UserInfo u =new UserInfo();
10             u.UserName=uname;
11             u.Pwd=pwd;
12             var t = UserInfoService.Add(u);
13             session.SaveChanges();
14             if(t.Id>0){
15                 return Content("注冊成功!");
16             }
17             else{
18                 return Content("注冊失敗!");
19             }
20         }

 

本文如果有什么錯誤或各位大神有什么建議和不同理解,可以回復交流一下,讓本文達到拋磚引玉的目的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM