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 }