爲何要本身搭框架?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 }
數據訪問基類接口
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 }
數據訪問實現基類
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 }
數據庫訪問上下文
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 }
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 }
擴展幫助類
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 }
分頁控件
我用得是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 }
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>
分頁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;}
怎麼調用呢?跟調用分部試圖方法同樣,只是須要傳進一個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 }
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" })
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 }
經過控制器裏的構造方法,調用便可
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 }
其實配置接口對應哪一個具體實體的關係,應該放到config文件比較好,這個後期再慢慢優化把。
結尾
這是一個初級版本,後期確定要再好好完善,好比加入Transaction事務管理,排序,條件查詢等等。
你們若是有什麼好的建議,儘管提,互相促進互相學習。
轉載請註明出處,謝謝!
源代碼下載地址:http://yun.baidu.com/share/link?shareid=2761504180&uk=2820969304