MVC項目搭建筆記----
項目架構采用ASP.NET MVC+Entity Framwork+Spring.Net等技術搭建,搭建過程内容比較多,結合了抽象工廠的思想降低了三層之間的耦合,可以使用此套架構進行可擴充性要求高的企業級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類。
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 IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
40 {
41 return db.Set<T>().Where(whereLambda).AsQueryable();
42 }
43
44 public IQueryable<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();
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();
66 }
67 }
68 }
在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 IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
8 IQueryable<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 IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
8
9 IQueryable<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 partial class UserInfoService:BaseService<UserInfo>,IUserInfoService
2 {
3 public override void SetCurrentDal()
4 {
5 CurrentDal = DbSession.UserInfoDal;
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 }