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


    为什么要自己搭框架?

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

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

    要花费不少时间。

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

    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,现在这个类只有两个属性,等之后慢慢扩展完善  

     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

  • 相关阅读:
    鸟哥的Linux私房菜学习笔记(1)
    Linux下搭建Oracle11g RAC(4)----配置oracle,grid用户SSH对等性
    解决升级windows8.1 Oracle服务被刷新
    Linux下搭建Oracle11g RAC(3)----创建用户及配置相关文件
    Linux下搭建Oracle11g RAC(2)----配置DNS服务器,确认SCAN IP可以被解析
    Linux下搭建Oracle11g RAC(1)----IP分配与配置IP
    Oracle11g新特性导致空表不能导出问题
    svn is already locked 最终解决方案
    .cur 图片加载提示 You may need an appropriate loader to handle this file type
    Request header field userRole is not allowed by Access-Control-Allow-Headers in preflight response.
  • 原文地址:https://www.cnblogs.com/sggx/p/4555255.html
Copyright © 2020-2023  润新知