转载

Asp.net MVC 搭建属于自己的框架(一)

为什么要自己搭框架?

大家伙别急,让我慢慢地告诉你!大家有没有这种感觉,从一家跳槽到另一家公司,公司的框架往往是不相同的,这样你必须就得摒弃原来的,学习新的框架。

问题是你用习惯了一种框架,比如封装的扩展方法、工厂模式、实体映射等等,你用得很爽,但是跳槽到新的公司,又得学习他们公司的框架,往往你在这上面

要花费不少时间。

所以 我才有了搭建自己的框架的想法,我的框架用到了EntityFramework6.0+Asp.NET MVC4+Autofac等,下面是我的框架结构:

Asp.net  MVC 搭建属于自己的框架(一)

MyFrame.Domain 实体模型层

MyFrame.DataMapping 数据映射层:映射实体类和数据库表关系,数据库上下文存放在该层

MyFrame.IDao 数据访问接口层

MyFrame.Dao 数据访问层

MyFrame.IService 业务逻辑接口层

MyFrame.Service 业务逻辑层

MyFrame.Common 通用扩展层

MyFrame.Web UI层

层与层之间的引用关系

Domain(最低层)=》每个层调用;IDao=>Dao,Service; IService=>Service ; IDao,IService=>Web

实体基类

MyFrame.Domain.DomainBase:实体基类,实体类都需要继承DomainBase,现在这个类只有两个属性,等之后慢慢扩展完善

Asp.net  MVC 搭建属于自己的框架(一)
 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:封装了增删改查方法以及分页等

Asp.net  MVC 搭建属于自己的框架(一)
 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

Asp.net  MVC 搭建属于自己的框架(一)
  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

Asp.net  MVC 搭建属于自己的框架(一)
 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
Asp.net  MVC 搭建属于自己的框架(一)
 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:封装了一些常用的方法,我自己用起来比较顺手,增加自己的开发效率

Asp.net  MVC 搭建属于自己的框架(一)
  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,

为什么要自己写个而不是用它自己封装好的,因为后期页码可能需要跳转“首页”,”末页“等

Asp.net  MVC 搭建属于自己的框架(一)
 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
Asp.net  MVC 搭建属于自己的框架(一)
 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

Asp.net  MVC 搭建属于自己的框架(一)
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

Asp.net  MVC 搭建属于自己的框架(一)
 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
Asp.net  MVC 搭建属于自己的框架(一)
 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里配置

Asp.net  MVC 搭建属于自己的框架(一)
 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

通过控制器里的构造方法,调用即可

Asp.net  MVC 搭建属于自己的框架(一)
 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事务管理,排序,条件查询等等。

大家如果有什么好的建议,尽管提,互相促进互相学习。

转载请注明出处,谢谢!

正文到此结束
Loading...