为什么要自己搭框架?

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

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

要花费不少时间。

所以我才有了搭建自己的框架的想法,我的框架用到了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 搭建属于自己的框架(一)的更多相关文章

  1. ASP.NET MVC搭建项目后台UI框架—1、后台主框架

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  2. ASP.NET MVC搭建项目后台UI框架—11、自动加载下拉框查询

    ASP.NET MVC搭建项目后台UI框架—1.后台主框架 需求:在查询记录的时候,输入第一个字,就自动把以这个字开头的相关记录查找出来,输入2个字就过滤以这两个子开头的记录,依次类推. 突然要用到这 ...

  3. ASP.NET MVC搭建项目后台UI框架—2、菜单特效

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  4. ASP.NET MVC搭建项目后台UI框架—3、面板折叠和展开

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  5. ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  6. 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 ...

  7. ASP.NET MVC搭建项目后台UI框架—6、客户管理(添加、修改、查询、分页)

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  8. ASP.NET MVC搭建项目后台UI框架—7、统计报表

    ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NET M ...

  9. ASP.NET MVC搭建项目后台UI框架—8、将View中选择的数据行中的部分数据传入到Controller中

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  10. ASP.NET MVC搭建项目后台UI框架—9、服务器端排序

    ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NET M ...

随机推荐

  1. 常用vi编辑命令

    在自己的博客里存起来,这么多全记住确实有点难,时不时的翻一翻到是可以的. 摘自:http://www.cnblogs.com/junw_china/articles/1708967.html 光标控制 ...

  2. sass+compass+bootstrap三剑合璧高效开发记录

    1. 先搭建环境,下载node.js,rubyinstaller,安装, 安装rubyinstaller时,要选上include system path,这样就会自动将node.js执行添加到wind ...

  3. 对于这个函数const int func(const int& a) const声明中,三个const分别是什么意思?

    第一个const 函数的返回值类型是const. 这个const修饰没什么意义,你可以想象一下: 既然是函数的 返回值,而且是值传递的形式,是否const有什么意义.如果指针(引用)传递,怎表示返回值 ...

  4. 限制input输入类型(多种方法实现)

    1.只能输入和粘贴汉字 <input onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" onbeforepaste= ...

  5. Hadoop with tool interface

    Often Hadoop jobsare executed through a command line. Therefore, each Hadoop job has to support read ...

  6. 关于CSS中的字体尺寸设置 em rem等

    常用单位 在CSS中可以用很多不同的方式来设定字体的尺寸.一般来说,这些单位被分成两大类:绝对单位(absolute)和相对单位(relative). 绝对单位在大多数情况下是相对于某些实际量度而言的 ...

  7. unity3d Aniso Level 摄像机近地面清楚,远地面模糊

    设置方法 选中贴图 在属性面板,拖动Aniso Level的值从0~9改变,值越大贴图越清晰,但是消耗也变大,文档说会造成显卡消耗,一般只用在地面上,其他地方没必要 遇到的问题 但是打包到Ipod上面 ...

  8. TestLink学习六:TestLink1.9.13工作使用小结

    Testlink是一款强大的用例追踪和管理工具.测试管理注重的实际上就是一个流程. 1.默认当测试用例同名时,就会有提示.(以前版本需要修改配置) 2.测试用例序号:(缺点) 1)删除一个测试用例之后 ...

  9. Eclipse去除JavaScript验证错误

    这篇文章主要是对Eclipse去除js(JavaScript)验证错误进行了介绍.在Eclipse中,js文件常常会报错.可以通过如下几个步骤解决 第一步: 去除eclipse的JS验证: 将wind ...

  10. java 15-1 Collection集合的概述以及小功能介绍

     集合的由来:  我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.  而要想存储多个对象,就不能是一个基本的变量,而应 ...