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,现在这个类只有两个属性,等之后慢慢扩展完善
- using System;
- namespace MyFrame.Domain
- {
- /// <summary>
- /// 实体基类
- /// </summary>
- public class DomainBase
- {
- /// <summary>
- /// 编号
- /// </summary>
- public int Id { get; set; }
- /// <summary>
- /// 创建时间
- /// </summary>
- public DateTime CreateTime { get; set; }
- }
- }
DomainBase
数据访问基类接口
MyFrame.IDao.IDaoBase:封装了增删改查方法以及分页等
- using System.Collections.Generic;
- using PagedList;
- namespace MyFrame.IDao
- {
- /// <summary>
- /// 数据访问层的基类接口
- /// </summary>
- public interface IDaoBase<T> where T:class
- {
- /// <summary>
- /// 增加
- /// </summary>
- /// <param name="domain">实体</param>
- /// <returns></returns>
- int Insert(T domain);
- /// <summary>
- /// 通过Id删除
- /// </summary>
- /// <param name="id">Id</param>
- /// <returns></returns>
- bool Delete(int id);
- /// <summary>
- /// 删除
- /// </summary>
- /// <param name="domain">实体</param>
- /// <returns></returns>
- bool Delete(T domain);
- /// <summary>
- /// 更新操作
- /// </summary>
- /// <param name="domain">实体</param>
- /// <returns></returns>
- bool Update(T domain);
- /// <summary>
- /// 通过Id查询
- /// </summary>
- /// <param name="id">Id</param>
- /// <returns></returns>
- T SelectById(int id);
- /// <summary>
- /// 查询所有
- /// </summary>
- /// <returns></returns>
- IEnumerable<T> SelectAll();
- /// <summary>
- /// 分页查询
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="pageIndex"></param>
- /// <param name="pageSize"></param>
- /// <returns></returns>
- IPagedList<T> SelectPageList(int? pageIndex = , int? pageSize = );
- }
- }
IDaoBase
数据访问实现基类
MyFrame.Dao.DaoBase:需要继承IDaoBase,IDisposable
- using System;
- using System.Collections.Generic;
- using System.Data.Entity;
- using System.Linq;
- using MyFrame.Domain;
- using MyFrame.IDao;
- using MyFrame.DataMapping;
- using PagedList;
- namespace MyFrame.Dao
- {
- /// <summary>
- /// 数据访问层基类
- /// </summary>
- public class DaoBase<T> : IDisposable, IDaoBase<T> where T : DomainBase
- {
- protected readonly DbContext DbContext;
- public DaoBase()
- {
- DbContext = new DataBaseContext();
- }
- public int Insert(T t)
- {
- t.CreateTime = DateTime.Now;
- DbContext.Entry<T>(t);
- DbContext.Set<T>().Add(t);
- return SaveChanges();
- }
- public bool Delete(int id)
- {
- T domain = DbContext.Set<T>().FirstOrDefault(s => s.Id == id);
- if (domain == null)
- return false;
- DbContext.Set<T>().Attach(domain);
- DbContext.Set<T>().Remove(domain);
- return SaveChanges() > ;
- }
- public bool Delete(T t)
- {
- DbContext.Set<T>().Attach(t);
- DbContext.Set<T>().Remove(t);
- return SaveChanges() > ;
- }
- public bool Update(T t)
- {
- DbContext.Set<T>().Attach(t);
- DbContext.Entry(t).State = EntityState.Modified;
- return SaveChanges() > ;
- }
- public T SelectById(int id)
- {
- return DbContext.Set<T>().FirstOrDefault(s => s.Id == id);
- }
- public IEnumerable<T> SelectAll()
- {
- return DbContext.Set<T>();
- }
- public IPagedList<T> SelectPageList(int? pageIndex, int? pageSize)
- {
- IEnumerable<T> list = DbContext.Set<T>().OrderByDescending(s=>s.CreateTime);
- return list.ToPagedList(pageIndex??,pageSize??);
- }
- /// <summary>
- /// 提交数据库操作进行异常捕捉
- /// </summary>
- /// <returns></returns>
- private int SaveChanges()
- {
- try
- {
- int result = DbContext.SaveChanges();
- return result;
- }
- catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
- {
- string message = "error:";
- if (ex.InnerException == null)
- message += ex.Message + ",";
- else if (ex.InnerException.InnerException == null)
- message += ex.InnerException.Message + ",";
- else if (ex.InnerException.InnerException.InnerException == null)
- message += ex.InnerException.InnerException.Message + ",";
- throw new Exception(message);
- }
- }
- public void Dispose()
- {
- DbContext.Dispose();
- }
- }
- }
DaoBase
数据库访问上下文
MyFrame.DataMapping.DataBaseContext
- using System.Data.Entity;
- using MyFrame.DataMapping.Mapping;
- using MyFrame.Domain;
- namespace MyFrame.DataMapping
- {
- /// <summary>
- /// 数据库访问上下文
- /// </summary>
- public class DataBaseContext : DbContext
- {
- public DataBaseContext()
- : base("Name=EhiBus")
- {
- Database.SetInitializer<DataBaseContext>(null);
- }
- //实体类
- public DbSet<User> Users { get; set; }
- public DbSet<Driver> Drivers { get; set; }
- //将实体映射到数据库表
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Configurations.Add(new UserMap());
- modelBuilder.Configurations.Add(new DriverMap());
- }
- }
- }
DataBaseContext
- using System.Data.Entity.ModelConfiguration;
- using MyFrame.Domain;
- namespace MyFrame.DataMapping.Mapping
- {
- public class UserMap : EntityTypeConfiguration<User>
- {
- public UserMap()
- {
- this.HasKey(t => t.Id);
- this.ToTable("User");
- this.Property(t => t.Id).HasColumnName("Id");
- this.Property(t => t.CreateTime).HasColumnName("CreateTime");
- }
- }
- }
UserMap
扩展帮助类
MyFrame.Common.Helper:封装了一些常用的方法,我自己用起来比较顺手,增加自己的开发效率
- using System;
- namespace MyFrame.Common
- {
- public static class Helper
- {
- #region 字符串转换为Int
- /// <summary>
- /// 将字符串转换为Int?类型
- /// </summary>
- public static int? ToInt32(this string s)
- {
- int? num;
- try
- {
- num = Convert.ToInt32(s);
- }
- catch (FormatException formatException)
- {
- num = null;
- }
- catch (OverflowException overflowException)
- {
- num = null;
- }
- return num;
- }
- /// <summary>
- /// 将字符串转换为Int类型
- /// </summary>
- public static int ToInt32Req(this string s)
- {
- try
- {
- int num = Convert.ToInt32(s);
- return num;
- }
- catch (FormatException ex)
- {
- throw new Exception(ex.Message);
- }
- catch (OverflowException overflowException)
- {
- throw new Exception(overflowException.Message);
- }
- }
- #endregion
- #region 字符串转换为Decimal
- /// <summary>
- /// 将字符串转换为Decimal?类型
- /// </summary>
- public static decimal? ToDecimal(this string s)
- {
- decimal? num;
- try
- {
- num = Convert.ToDecimal(s);
- }
- catch (Exception formatException)
- {
- num = null;
- }
- return num;
- }
- /// <summary>
- /// 将字符串转换为Decimal类型,无法转换抛出异常
- /// </summary>
- public static decimal ToDecimalReq(this string s)
- {
- try
- {
- decimal num = Convert.ToDecimal(s);
- return num;
- }
- catch (FormatException ex)
- {
- throw new Exception(ex.Message);
- }
- catch (OverflowException overflowException)
- {
- throw new Exception(overflowException.Message);
- }
- }
- #endregion
- #region 字符串转换为DateTime
- /// <summary>
- /// 将字符串转换为DateTime?类型
- /// </summary>
- public static DateTime? ToDateTime(this string s)
- {
- DateTime? num;
- try
- {
- num = Convert.ToDateTime(s);
- }
- catch (FormatException formatException)
- {
- num = null;
- }
- return num;
- }
- /// <summary>
- /// 将字符串转换为DateTime类型,无法转换抛出异常
- /// </summary>
- public static DateTime ToDateTimeReq(this string s)
- {
- try
- {
- DateTime num = Convert.ToDateTime(s);
- return num;
- }
- catch (FormatException ex)
- {
- throw new Exception(ex.Message);
- }
- }
- #endregion
- #region 字符串转换为bool
- /// <summary>
- /// 将字符串转换为bool?类型
- /// </summary>
- public static bool? ToBool(this string s)
- {
- bool? num;
- try
- {
- num = Convert.ToBoolean(s);
- }
- catch (FormatException formatException)
- {
- num = null;
- }
- return num;
- }
- /// <summary>
- /// 将字符串转换为bool类型,无法转换抛出异常
- /// </summary>
- public static bool ToBoolReq(this string s)
- {
- try
- {
- bool num = Convert.ToBoolean(s);
- return num;
- }
- catch (FormatException ex)
- {
- throw new Exception(ex.Message);
- }
- }
- #endregion
- #region 根据Text转换为Enum
- /// <summary>
- /// 根据Text转换为Enum?类型
- /// </summary>
- public static T? ToEnumByText<T>(this string s) where T:struct
- {
- T? t;
- try
- {
- t = (T) Enum.Parse(typeof (T), s);
- }
- catch (Exception ex)
- {
- t = null;
- }
- return t;
- }
- /// <summary>
- ///根据Text转换为Enum类型,无法转换抛出异常
- /// </summary>
- public static T ToEnumReqByText<T>(this string s) where T : struct
- {
- try
- {
- T t= (T)Enum.Parse(typeof (T), s);
- return t;
- }
- catch (ArgumentNullException argumentNullException)
- {
- throw new Exception(argumentNullException.Message);
- }
- catch (ArgumentException argumentException)
- {
- throw new Exception(argumentException.Message);
- }
- catch (OverflowException overflowException)
- {
- throw new Exception(overflowException.Message);
- }
- }
- #endregion
- #region 根据Value转换为Enum
- /// <summary>
- /// 根据Value转换为Enum?类型
- /// </summary>
- public static T? ToEnumByValue<T>(this int s) where T : struct
- {
- T? t;
- try
- {
- t = (T)Enum.Parse(typeof(T), s.ToString());
- }
- catch (Exception ex)
- {
- t = null;
- }
- return t;
- }
- /// <summary>
- ///根据Value转换为Enum类型,无法转换抛出异常
- /// </summary>
- public static T ToEnumByValueReq<T>(this int s) where T : struct
- {
- try
- {
- T t = (T)Enum.Parse(typeof(T), s.ToString());
- return t;
- }
- catch (ArgumentNullException argumentNullException)
- {
- throw new Exception(argumentNullException.Message);
- }
- catch (ArgumentException argumentException)
- {
- throw new Exception(argumentException.Message);
- }
- catch (OverflowException overflowException)
- {
- throw new Exception(overflowException.Message);
- }
- }
- #endregion
- }
- }
Helper
分页控件
我用得是PagedList,Nuget里搜索安装PagedList.MVC即可,然后自己封装了一下,封装得在DaoBase里SelectPageList()
为了让这个控件扩展性更强,写了一个分部试图_PageList,定义了一个分页Model,
为什么要自己写个而不是用它自己封装好的,因为后期页码可能需要跳转“首页”,”末页“等
- using PagedList;
- namespace MyFrame.Web.Models
- {
- public class PageListModel<T> where T:class
- {
- public IPagedList<T> PageList { get; set; }
- public string Action { get; set; }
- public string Controller { get; set; }
- }
- }
PageListModel
- <div class="page-box">
- @if (Model.PageList.HasPreviousPage)
- {
- <a href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = (Model.PageList.PageNumber - 1) })">上一页</a>
- }
- @for (int i = ; i <= Model.PageList.PageCount; i++)
- {
- <a class="@(i == Model.PageList.PageNumber ? "currentpage" : "")" href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = i })">@i</a>
- }
- @if (Model.PageList.HasNextPage)
- {
- <a href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = (Model.PageList.PageNumber + 1) })">下一页</a>
- }
- </div>
_PageList
分页css
- /*分页*/
- .page-box{ width:770px; height:40px; background:#FFF; padding-top:15px; text-align:right; padding-right:20px;}
- .page-box a{text-decoration: none; padding:3px 7px; display:inline-block; text-align:center; border:1px solid #CFCFCF; color:#666; font-size:12px;}
- .page-box a:hover{ background:#A4A4A4; color:#fff;}
- .page-box .currentpage{ background:#CCC;}
PageList
怎么调用呢?跟调用分部试图方法一样,只是需要传进一个PageListModel
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using MyFrame.Common;
- using MyFrame.Domain;
- using MyFrame.Dao;
- using MyFrame.IDao;
- using PagedList;
- namespace MyFrame.Web.Controllers
- {
- public class HomeController : Controller
- {
- private readonly IUserDao _userDao;
- private readonly IDriverDao _driverDao;
- public HomeController(IUserDao userDao,IDriverDao driverDao)
- {
- _userDao = userDao;
- _driverDao = driverDao;
- }
- public ActionResult Index(int? pageIndex=)
- {
- IPagedList<Driver> drivers = _driverDao.SelectPageList(pageIndex,);
- return View(drivers);
- }
- }
- }
Controller
- @using MyFrame.Domain
- @using MyFrame.Web.Models
- @model PagedList.IPagedList<MyFrame.Domain.Driver>
- @{
- ViewBag.Title = "Index";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- @foreach (var driver in Model)
- {
- <p>@driver.Id</p>
- <p>@driver.DriverName</p>
- <p>@driver.Phone</p>
- }
- @Html.Partial("_PageList", new PageListModel<Driver> { PageList = Model, Action = "Index", Controller = "Home" })
Index
Autofac组件
控制反转,类似于Ioc容器的组件,通过配置接口对应具体的实现类
然后调用我们只需要调接口就行了,降低耦合性。
组件Nuget里有自己下载安装就行
在Globl.asax里配置
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Web;
- using System.Web.Http;
- using System.Web.Mvc;
- using System.Web.Optimization;
- using System.Web.Routing;
- using Autofac;
- using Autofac.Integration.Mvc;
- using MyFrame.Common;
- using MyFrame.Dao;
- using MyFrame.IDao;
- using MyFrame.IService;
- using MyFrame.Service;
- namespace MyFrame.Web
- {
- // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
- // 请访问 http://go.microsoft.com/?LinkId=9394801
- public class MvcApplication : System.Web.HttpApplication
- {
- private void SetupResolveRules(ContainerBuilder builder)
- {
- //Components are wired to services using the As() methods on ContainerBuilder
- builder.RegisterType<UserDao>().As<IUserDao>();
- builder.RegisterType<UserService>().As<IUserService>();
- builder.RegisterType<DriverDao>().As<IDriverDao>();
- }
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- // 依赖注入
- var builder = new ContainerBuilder();
- SetupResolveRules(builder);
- builder.RegisterControllers(Assembly.GetExecutingAssembly());
- var container = builder.Build();
- DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
- WebApiConfig.Register(GlobalConfiguration.Configuration);
- FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- BundleConfig.RegisterBundles(BundleTable.Bundles);
- }
- }
- }
通过控制器里的构造方法,调用即可
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using MyFrame.Common;
- using MyFrame.Domain;
- using MyFrame.Dao;
- using MyFrame.IDao;
- using PagedList;
- namespace MyFrame.Web.Controllers
- {
- public class HomeController : Controller
- {
- private readonly IUserDao _userDao;
- private readonly IDriverDao _driverDao;
- public HomeController(IUserDao userDao,IDriverDao driverDao)
- {
- _userDao = userDao;
- _driverDao = driverDao;
- }
- public ActionResult Index(int? pageIndex=)
- {
- IPagedList<Driver> drivers = _driverDao.SelectPageList(pageIndex,);
- return View(drivers);
- }
- }
- }
其实配置接口对应哪个具体实体的关系,应该放到config文件比较好,这个后期再慢慢优化把。
结尾
这是一个初级版本,后期肯定要再好好完善,比如加入Transaction事务管理,排序,条件查询等等。
大家如果有什么好的建议,尽管提,互相促进互相学习。
转载请注明出处,谢谢!
源代码下载地址:http://yun.baidu.com/share/link?shareid=2761504180&uk=2820969304
Asp.net MVC 搭建属于自己的框架(一)的更多相关文章
- ASP.NET MVC搭建项目后台UI框架—1、后台主框架
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—11、自动加载下拉框查询
ASP.NET MVC搭建项目后台UI框架—1.后台主框架 需求:在查询记录的时候,输入第一个字,就自动把以这个字开头的相关记录查找出来,输入2个字就过滤以这两个子开头的记录,依次类推. 突然要用到这 ...
- ASP.NET MVC搭建项目后台UI框架—2、菜单特效
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—3、面板折叠和展开
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—5、Demo演示Controller和View的交互
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—6、客户管理(添加、修改、查询、分页)
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—7、统计报表
ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NET M ...
- ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中
目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...
- ASP.NET MVC搭建项目后台UI框架—9、服务器端排序
ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NET M ...
随机推荐
- Redis高级应用
上一篇博文讲述了Redis的一些常用命令,可以对数据库及数据库服务器进行操作,本篇将讲述Redis的高级应用及配置 安全性 设置密码:修改redis.conf中的requirepass,在其后面添加密 ...
- I2C 总线协议
1.I2C协议 2条双向串行线,一条数据线SDA,一条时钟线SCL. SDA传输数据是大端传输,每次传输8bit,即一字节. 支持多主控(multimastering),任何时间点只能 ...
- uniq
-c, --count 在每行前加上表示相应行目出现次数的前缀编号-d, --repeated 只输出重复的行-D, --all-repeated[=delimit-method 显示所有重复的行de ...
- 修改镜像文件EI.CFG
一.EI.cfg说明 Windows 7 安装光盘中存在着 SOURCES\EI.CFG 这样一个配置文件.EI.cfg 是特定于 Windows 安装程序的配置文件,用于确定在安装过程中应该使用哪种 ...
- [转]Ionic最佳实践-使用模态窗口modal
本文转自:http://m.blog.csdn.net/blog/betreex/45649689 原文地址:Ionic最佳实践-使用模态窗口modal 模态窗口的结构 在Ionic中,模态窗口通过$ ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 (第一,二,三,,四,五章)
SQL - Structured Query Language (结构化查询语言) 1/ SQL 命令的类型 : 数据定义语言: DDL 数据操作语言: DML 数据查询语言: DQL 数据控制语言 ...
- McCall的软件质量模型
McCall等认为,特性是软件质量的反映,软件属性可用做评价准则,定量化地度量软件属性可知软件质量的优劣 McCall认为软件的质量模型应该包括 产品的修正.产品的转移,产品的运行 而产品的修正又包括 ...
- 原生js实现增加(addclass),删除(removeclass),判断是否存在(hasclass),如果存在删除,如果不存在添加(toggleclass)和获取类名(getbyclass)的方法
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- CSS3中的字体rem
rem和em都是相对单位,em相对父元素的font-size来计算,而rem是根据文档根元素(html)的font-size大小来计算的 通常将html的字体大小设为62.5%(等于10px),当然也 ...
- UOJ 151 斗地主“加强”版
#151. [NOIP2015]斗地主“加强”版 统计 描述 提交 自定义测试 本题开放Hack 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54 ...