Asp.net MVC 搭建屬於本身的框架(一)

爲何要本身搭框架?css

  你們夥別急,讓我慢慢地告訴你!你們有沒有這種感受,從一家跳槽到另外一家公司,公司的框架每每是不相同的,這樣你必須就得摒棄原來的,學習新的框架。html

問題是你用習慣了一種框架,好比封裝的擴展方法、工廠模式、實體映射等等,你用得很爽,可是跳槽到新的公司,又得學習他們公司的框架,每每你在這上面數據庫

要花費很多時間。app

因此我纔有了搭建本身的框架的想法,個人框架用到了EntityFramework6.0+Asp.NET MVC4+Autofac等,下面是個人框架結構:框架

 

MyFrame.Domain 實體模型層dom

MyFrame.DataMapping 數據映射層:映射實體類和數據庫表關係,數據庫上下文存放在該層ide

MyFrame.IDao 數據訪問接口層學習

MyFrame.Dao 數據訪問層優化

MyFrame.IService 業務邏輯接口層ui

MyFrame.Service 業務邏輯層

MyFrame.Common 通用擴展層

MyFrame.Web UI層

層與層之間的引用關係

  Domain(最低層)=》每一個層調用;IDao=>Dao,Service; IService=>Service ; IDao,IService=>Web

實體基類
  MyFrame.Domain.DomainBase:實體基類,實體類都須要繼承DomainBase,如今這個類只有兩個屬性,等以後慢慢擴展完善  

 1 using System;
 2 
 3 namespace MyFrame.Domain
 4 {
 5     /// <summary>
 6     /// 實體基類
 7     /// </summary>
 8     public class DomainBase
 9     {
10         /// <summary>
11         /// 編號
12         /// </summary>
13         public int Id { get; set; }
14 
15         /// <summary>
16         /// 建立時間
17         /// </summary>
18         public DateTime CreateTime { get; set; }
19     }
20 }
DomainBase

數據訪問基類接口 

MyFrame.IDao.IDaoBase:封裝了增刪改查方法以及分頁等

 1 using System.Collections.Generic;
 2 using PagedList;
 3 
 4 namespace MyFrame.IDao
 5 {
 6     /// <summary>
 7     /// 數據訪問層的基類接口
 8     /// </summary>
 9     public interface IDaoBase<T> where T:class 
10     {
11         /// <summary>
12         /// 增長
13         /// </summary>
14         /// <param name="domain">實體</param>
15         /// <returns></returns>
16         int Insert(T domain);
17 
18         /// <summary>
19         /// 經過Id刪除
20         /// </summary>
21         /// <param name="id">Id</param>
22         /// <returns></returns>
23         bool Delete(int id);
24 
25         /// <summary>
26         /// 刪除
27         /// </summary>
28         /// <param name="domain">實體</param>
29         /// <returns></returns>
30         bool Delete(T domain);
31 
32         /// <summary>
33         /// 更新操做
34         /// </summary>
35         /// <param name="domain">實體</param>
36         /// <returns></returns>
37         bool Update(T domain);
38 
39         /// <summary>
40         /// 經過Id查詢
41         /// </summary>
42         /// <param name="id">Id</param>
43         /// <returns></returns>
44         T SelectById(int id);
45 
46         /// <summary>
47         /// 查詢全部
48         /// </summary>
49         /// <returns></returns>
50         IEnumerable<T> SelectAll();
51 
52         /// <summary>
53         /// 分頁查詢
54         /// </summary>
55         /// <typeparam name="T"></typeparam>
56         /// <param name="pageIndex"></param>
57         /// <param name="pageSize"></param>
58         /// <returns></returns>
59         IPagedList<T> SelectPageList(int? pageIndex = 1, int? pageSize = 10);
60     }
61 }
IDaoBase

數據訪問實現基類

MyFrame.Dao.DaoBase:須要繼承IDaoBase,IDisposable

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data.Entity;
  4 using System.Linq;
  5 using MyFrame.Domain;
  6 using MyFrame.IDao;
  7 using MyFrame.DataMapping;
  8 using PagedList;
  9 
 10 namespace MyFrame.Dao
 11 {
 12     /// <summary>
 13     /// 數據訪問層基類
 14     /// </summary>
 15     public class DaoBase<T>  : IDisposable, IDaoBase<T> where T : DomainBase 
 16     {
 17         protected readonly DbContext DbContext;
 18 
 19         public DaoBase()
 20         {
 21             DbContext = new DataBaseContext();
 22         }
 23 
 24         public  int Insert(T t)
 25         {
 26             t.CreateTime = DateTime.Now;
 27             DbContext.Entry<T>(t);
 28             DbContext.Set<T>().Add(t);
 29             return SaveChanges();
 30         }
 31 
 32         public bool Delete(int id)
 33         {
 34             T domain = DbContext.Set<T>().FirstOrDefault(s => s.Id == id);
 35             if (domain == null)
 36                 return false;
 37             DbContext.Set<T>().Attach(domain);
 38             DbContext.Set<T>().Remove(domain);
 39             return SaveChanges() > 0;
 40         }
 41 
 42         public bool Delete(T t)
 43         {
 44             DbContext.Set<T>().Attach(t);
 45             DbContext.Set<T>().Remove(t);
 46             return SaveChanges() > 0;
 47         }
 48 
 49         public bool Update(T t)
 50         {
 51             DbContext.Set<T>().Attach(t);
 52             DbContext.Entry(t).State = EntityState.Modified;
 53             return SaveChanges() > 0;
 54         }
 55 
 56         public T SelectById(int id)
 57         {
 58             return DbContext.Set<T>().FirstOrDefault(s => s.Id == id);
 59         }
 60 
 61         public IEnumerable<T> SelectAll()
 62         {
 63             return DbContext.Set<T>();
 64         }
 65 
 66         public IPagedList<T> SelectPageList(int? pageIndex, int? pageSize)
 67         {
 68             IEnumerable<T> list = DbContext.Set<T>().OrderByDescending(s=>s.CreateTime);
 69             return list.ToPagedList(pageIndex??1,pageSize??10);
 70         }
 71 
 72         /// <summary>
 73         /// 提交數據庫操做進行異常捕捉
 74         /// </summary>
 75         /// <returns></returns>
 76         private int SaveChanges()
 77         {
 78             try
 79             {
 80                 int result = DbContext.SaveChanges();
 81                 return result;
 82             }
 83             catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
 84             {
 85                 string message = "error:";
 86                 if (ex.InnerException == null)
 87                     message += ex.Message + ",";
 88                 else if (ex.InnerException.InnerException == null)
 89                     message += ex.InnerException.Message + ",";
 90                 else if (ex.InnerException.InnerException.InnerException == null)
 91                     message += ex.InnerException.InnerException.Message + ",";
 92                 throw new Exception(message);
 93             }
 94         }
 95 
 96         public void Dispose()
 97         {
 98             DbContext.Dispose();
 99         }
100     }
101 }
DaoBase

數據庫訪問上下文

MyFrame.DataMapping.DataBaseContext

 1 using System.Data.Entity;
 2 using MyFrame.DataMapping.Mapping;
 3 using MyFrame.Domain;
 4 
 5 namespace MyFrame.DataMapping
 6 {
 7     /// <summary>
 8     /// 數據庫訪問上下文
 9     /// </summary>
10     public class DataBaseContext : DbContext
11     {
12         public DataBaseContext()
13             : base("Name=EhiBus")
14         {
15             Database.SetInitializer<DataBaseContext>(null);
16         }
17         //實體類
18         public DbSet<User> Users { get; set; }
19         public DbSet<Driver> Drivers { get; set; }
20         //將實體映射到數據庫表
21         protected override void OnModelCreating(DbModelBuilder modelBuilder)
22         {
23             modelBuilder.Configurations.Add(new UserMap());
24             modelBuilder.Configurations.Add(new DriverMap());
25         }
26         
27     }
28 }
DataBaseContext
 1 using System.Data.Entity.ModelConfiguration;
 2 using MyFrame.Domain;
 3 
 4 namespace MyFrame.DataMapping.Mapping
 5 {
 6     public class UserMap : EntityTypeConfiguration<User>
 7     {
 8         public UserMap()
 9         {
10             this.HasKey(t => t.Id);
11             this.ToTable("User");
12             this.Property(t => t.Id).HasColumnName("Id");
13             this.Property(t => t.CreateTime).HasColumnName("CreateTime");
14         }
15     }
16 }
UserMap

擴展幫助類

MyFrame.Common.Helper:封裝了一些經常使用的方法,我本身用起來比較順手,增長本身的開發效率

  1 using System;
  2 
  3 namespace MyFrame.Common
  4 {
  5     public static class Helper
  6     {
  7         #region 字符串轉換爲Int
  8         /// <summary>
  9         /// 將字符串轉換爲Int?類型
 10         /// </summary>
 11         public static int? ToInt32(this string s)
 12         {
 13             int? num;
 14             try
 15             {
 16                 num = Convert.ToInt32(s);
 17             }
 18             catch (FormatException formatException)
 19             {
 20                 num = null;
 21             }
 22             catch (OverflowException overflowException)
 23             {
 24                 num = null;
 25             }
 26             return num;
 27         }
 28         
 29         /// <summary>
 30         /// 將字符串轉換爲Int類型
 31         /// </summary>
 32         public static int ToInt32Req(this string s)
 33         {
 34             try
 35             {
 36                 int num = Convert.ToInt32(s);
 37                 return num;
 38             }
 39             catch (FormatException ex)
 40             {
 41                 throw new Exception(ex.Message);
 42             }
 43             catch (OverflowException overflowException)
 44             {
 45                 throw new Exception(overflowException.Message);
 46             }
 47         }
 48         #endregion
 49 
 50         #region 字符串轉換爲Decimal
 51         /// <summary>
 52         /// 將字符串轉換爲Decimal?類型
 53         /// </summary>
 54         public static decimal? ToDecimal(this string s)
 55         {
 56             decimal? num;
 57             try
 58             {
 59                 num = Convert.ToDecimal(s);
 60             }
 61             catch (Exception formatException)
 62             {
 63                 num = null;
 64             }
 65             return num;
 66         }
 67 
 68         /// <summary>
 69         /// 將字符串轉換爲Decimal類型,沒法轉換拋出異常
 70         /// </summary>
 71         public static decimal ToDecimalReq(this string s)
 72         {
 73             try
 74             {
 75                 decimal num = Convert.ToDecimal(s);
 76                 return num;
 77             }
 78             catch (FormatException ex)
 79             {
 80                 throw new Exception(ex.Message);
 81             }
 82             catch (OverflowException overflowException)
 83             {
 84                 throw new Exception(overflowException.Message);
 85             }
 86         }
 87         #endregion
 88 
 89         #region 字符串轉換爲DateTime
 90         /// <summary>
 91         /// 將字符串轉換爲DateTime?類型
 92         /// </summary>
 93         public static DateTime? ToDateTime(this string s)
 94         {
 95             DateTime? num;
 96             try
 97             {
 98                 num = Convert.ToDateTime(s);
 99             }
100             catch (FormatException formatException)
101             {
102                 num = null;
103             }
104             return num;
105         }
106 
107         /// <summary>
108         /// 將字符串轉換爲DateTime類型,沒法轉換拋出異常
109         /// </summary>
110         public static DateTime ToDateTimeReq(this string s)
111         {
112             try
113             {
114                 DateTime num = Convert.ToDateTime(s);
115                 return num;
116             }
117             catch (FormatException ex)
118             {
119                 throw new Exception(ex.Message);
120             }
121         }
122         #endregion
123 
124         #region 字符串轉換爲bool
125         /// <summary>
126         /// 將字符串轉換爲bool?類型
127         /// </summary>
128         public static bool? ToBool(this string s)
129         {
130             bool? num;
131             try
132             {
133                 num = Convert.ToBoolean(s);
134             }
135             catch (FormatException formatException)
136             {
137                 num = null;
138             }
139             return num;
140         }
141 
142         /// <summary>
143         /// 將字符串轉換爲bool類型,沒法轉換拋出異常
144         /// </summary>
145         public static bool ToBoolReq(this string s)
146         {
147             try
148             {
149                 bool num = Convert.ToBoolean(s);
150                 return num;
151             }
152             catch (FormatException ex)
153             {
154                 throw new Exception(ex.Message);
155             }
156         }
157         #endregion
158 
159         #region 根據Text轉換爲Enum
160         /// <summary>
161         /// 根據Text轉換爲Enum?類型
162         /// </summary>
163         public static T? ToEnumByText<T>(this string s) where T:struct 
164         {
165             T? t;
166             try
167             {
168                 t = (T) Enum.Parse(typeof (T), s);
169             }
170             catch (Exception ex)
171             {
172                 t = null;
173             }
174             return t;
175         }
176 
177         /// <summary>
178         ///根據Text轉換爲Enum類型,沒法轉換拋出異常
179         /// </summary>
180         public static T ToEnumReqByText<T>(this string s) where T : struct 
181         {
182 
183             try
184             {
185                 T t= (T)Enum.Parse(typeof (T), s);
186                 return t;
187             }
188             catch (ArgumentNullException argumentNullException)
189             {
190                 throw new Exception(argumentNullException.Message);
191             }
192             catch (ArgumentException argumentException)
193             {
194                 throw new Exception(argumentException.Message);
195             }
196             catch (OverflowException overflowException)
197             {
198                 throw new Exception(overflowException.Message);
199             }
200         }
201         #endregion
202 
203         #region 根據Value轉換爲Enum
204         /// <summary>
205         /// 根據Value轉換爲Enum?類型
206         /// </summary>
207         public static T? ToEnumByValue<T>(this int s) where T : struct
208         {
209             T? t;
210             try
211             {
212                 t = (T)Enum.Parse(typeof(T), s.ToString());
213             }
214             catch (Exception ex)
215             {
216                 t = null;
217             }
218             return t;
219         }
220 
221         /// <summary>
222         ///根據Value轉換爲Enum類型,沒法轉換拋出異常
223         /// </summary>
224         public static T ToEnumByValueReq<T>(this int s) where T : struct
225         {
226 
227             try
228             {
229                 T t = (T)Enum.Parse(typeof(T), s.ToString());
230                 return t;
231             }
232             catch (ArgumentNullException argumentNullException)
233             {
234                 throw new Exception(argumentNullException.Message);
235             }
236             catch (ArgumentException argumentException)
237             {
238                 throw new Exception(argumentException.Message);
239             }
240             catch (OverflowException overflowException)
241             {
242                 throw new Exception(overflowException.Message);
243             }
244         }
245         #endregion
246 
247         
248     }
249 }
Helper

分頁控件

我用得是PagedList,Nuget裏搜索安裝PagedList.MVC便可,而後本身封裝了一下,封裝得在DaoBase裏SelectPageList()

爲了讓這個控件擴展性更強,寫了一個分部試圖_PageList,定義了一個分頁Model,

爲何要本身寫個而不是用它本身封裝好的,由於後期頁碼可能須要跳轉「首頁」,」末頁「等

 1 using PagedList;
 2 
 3 namespace MyFrame.Web.Models
 4 {
 5     public class PageListModel<T> where T:class 
 6     {
 7         public IPagedList<T> PageList { get; set; }
 8 
 9         public string Action { get; set; }
10 
11         public string Controller { get; set; }
12     }
13 }
PageListModel
 1 <div class="page-box">
 2     @if (Model.PageList.HasPreviousPage)
 3     {
 4         <a href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = (Model.PageList.PageNumber - 1) })">上一頁</a>
 5     }
 6     @for (int i = 1; i <= Model.PageList.PageCount; i++)
 7     {
 8         <a class="@(i == Model.PageList.PageNumber ? "currentpage" : "")" href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = i })">@i</a>
 9     }
10     @if (Model.PageList.HasNextPage)
11     {
12         <a href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = (Model.PageList.PageNumber + 1) })">下一頁</a>
13     }
14 </div>
_PageList

分頁css

1 /*分頁*/
2 .page-box{ width:770px; height:40px; background:#FFF; padding-top:15px; text-align:right; padding-right:20px;}
3 .page-box a{text-decoration: none; padding:3px 7px; display:inline-block; text-align:center; border:1px solid #CFCFCF; color:#666; font-size:12px;}
4 .page-box a:hover{ background:#A4A4A4; color:#fff;}
5 .page-box .currentpage{ background:#CCC;}
PageList

怎麼調用呢?跟調用分部試圖方法同樣,只是須要傳進一個PageListModel

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 using MyFrame.Common;
 7 using MyFrame.Domain;
 8 using MyFrame.Dao;
 9 using MyFrame.IDao;
10 using PagedList;
11 
12 namespace MyFrame.Web.Controllers
13 {
14     public class HomeController : Controller
15     {
16         private readonly IUserDao _userDao;
17         private readonly IDriverDao _driverDao;
18         public HomeController(IUserDao userDao,IDriverDao driverDao)
19         {
20             _userDao = userDao;
21             _driverDao = driverDao;
22         }
23 
24         public ActionResult Index(int? pageIndex=1)
25         {
26             IPagedList<Driver> drivers = _driverDao.SelectPageList(pageIndex,2);
27             return View(drivers);
28         }
29 
30     }
31 }
Controller
 1 @using MyFrame.Domain
 2 @using MyFrame.Web.Models
 3 @model PagedList.IPagedList<MyFrame.Domain.Driver>
 4 @{
 5     ViewBag.Title = "Index";
 6     Layout = "~/Views/Shared/_Layout.cshtml";
 7 }
 8 
 9 @foreach (var driver in Model)
10 {
11     <p>@driver.Id</p>
12     <p>@driver.DriverName</p>
13     <p>@driver.Phone</p>
14 
15 }
16 
17 @Html.Partial("_PageList", new PageListModel<Driver> { PageList = Model, Action = "Index", Controller = "Home" })
Index

Autofac組件

控制反轉,相似於Ioc容器的組件,經過配置接口對應具體的實現類

而後調用咱們只須要調接口就好了,下降耦合性。

組件Nuget裏有本身下載安裝就行

在Globl.asax裏配置

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Reflection;
 5 using System.Web;
 6 using System.Web.Http;
 7 using System.Web.Mvc;
 8 using System.Web.Optimization;
 9 using System.Web.Routing;
10 using Autofac;
11 using Autofac.Integration.Mvc;
12 using MyFrame.Common;
13 using MyFrame.Dao;
14 using MyFrame.IDao;
15 using MyFrame.IService;
16 using MyFrame.Service;
17 
18 namespace MyFrame.Web
19 {
20     // 注意: 有關啓用 IIS6 或 IIS7 經典模式的說明,
21     // 請訪問 http://go.microsoft.com/?LinkId=9394801
22 
23     public class MvcApplication : System.Web.HttpApplication
24     {
25 
26         private void SetupResolveRules(ContainerBuilder builder)
27         {
28             //Components are wired to services using the As() methods on ContainerBuilder
29             builder.RegisterType<UserDao>().As<IUserDao>();
30             builder.RegisterType<UserService>().As<IUserService>();
31             builder.RegisterType<DriverDao>().As<IDriverDao>();
32         }
33         protected void Application_Start()
34         {
35             AreaRegistration.RegisterAllAreas();
36 
37             // 依賴注入
38             var builder = new ContainerBuilder();
39             SetupResolveRules(builder);
40             builder.RegisterControllers(Assembly.GetExecutingAssembly());
41             var container = builder.Build();
42             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
43 
44             WebApiConfig.Register(GlobalConfiguration.Configuration);
45             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
46             RouteConfig.RegisterRoutes(RouteTable.Routes);
47             BundleConfig.RegisterBundles(BundleTable.Bundles);
48         }
49     }
50 }
View Code

經過控制器裏的構造方法,調用便可

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 using MyFrame.Common;
 7 using MyFrame.Domain;
 8 using MyFrame.Dao;
 9 using MyFrame.IDao;
10 using PagedList;
11 
12 namespace MyFrame.Web.Controllers
13 {
14     public class HomeController : Controller
15     {
16         private readonly IUserDao _userDao;
17         private readonly IDriverDao _driverDao;
18         public HomeController(IUserDao userDao,IDriverDao driverDao)
19         {
20             _userDao = userDao;
21             _driverDao = driverDao;
22         }
23 
24         public ActionResult Index(int? pageIndex=1)
25         {
26             IPagedList<Driver> drivers = _driverDao.SelectPageList(pageIndex,2);
27             return View(drivers);
28         }
29 
30     }
31 }
View Code

其實配置接口對應哪一個具體實體的關係,應該放到config文件比較好,這個後期再慢慢優化把。

結尾

這是一個初級版本,後期確定要再好好完善,好比加入Transaction事務管理,排序,條件查詢等等。

你們若是有什麼好的建議,儘管提,互相促進互相學習。

轉載請註明出處,謝謝!

源代碼下載地址http://yun.baidu.com/share/link?shareid=2761504180&uk=2820969304

相關文章
相關標籤/搜索