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 ...
随机推荐
- HTTPS(SSL/TLS) 原理之深入浅出
注:本文参考自网络上的多篇HTTPS相关文章,本人根据自己的理解,进行一些修改,综合. 1. 必要的加密解密基础知识 1)对称加密算法:就是加密和解密使用同一个密钥的加密算法.因为加密方和解密方使用的 ...
- MyCat 学习笔记 第十二篇.数据分片 之 分片事务处理
1 环境说明 VM 模拟3台MYSQL 5.6 服务器 VM1 192.168.31.187:3307 VM2 192.168.31.212:3307 VM3 192.168.31.150: 330 ...
- cocos2d-x之物理引擎之碰撞监测
#include "HelloWorldScene.h" USING_NS_CC; #define RED_BIT_MASK 0b0100 #define GREEN_BIT ...
- linux基本命令学习笔记
这个几天在研究linux的常用基本命令.以下是此时间内的幻灯片截图笔记,在这里留个脚印. linux 常用命令 1,命令的基本格式 2,文件处理命令 3,文件搜索命令 4,帮助命令 5,压缩解压缩命令 ...
- 如何删除TFS的Team Project
我们可以使用Visual Studio或Web新建一个TeamProject,但是删除时却没有一个合适的图形界面删除我们不想要的Team Project,所以此时就可以使用命令TFSDeletePro ...
- Linux系统搭建LAMP平台
知识背景(来自:百度百科): LAMP指的Linux(操作系统).Apache HTTP 服务器,MySQL(有时也指MariaDB,数据库软件) 和PHP(有时也是指Perl或Python) 的第一 ...
- linux硬链接与软链接
在linux操作系统中的文件数据除了实际的内容外,还会含有文件权限(rwx)与文件属性(owner,group,other等),文件系统通常会将这两部分的数据存放在不同的区块,文件权限与文件属性放置在 ...
- builder.properties
请加上这句话: javacDefaultEncoding.. = UTF-8
- Solr主从集群配置简要说明
关于solr的集群主要分为主从和SolrCloud两种.主从,比较适合以读为主的场景.SolrCloud适合数据量大,时不时会有更新的情形.那么solr的主从配置很简单.在solrconfig.xml ...
- tarjan算法求割点cojs 8
tarjan求割点:cojs 8. 备用交换机 ★★ 输入文件:gd.in 输出文件:gd.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] n个城市之间有通讯网 ...