为什么要自己搭框架?

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

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

要花费不少时间。

所以我才有了搭建自己的框架的想法,我的框架用到了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. Oracle与SQL SERVER编程差异分析(入门)

    网上有关Oracle与SQL SERVER性能差异的文章很多,结论往往是让你根据数据量与预算来选择数据库.但实际项目中,特别是使用 .Net 开发的系统,支持以上两种数据库或者更多已经成为Boss的普 ...

  2. html页面识别当前系统和语言

    项目中需要一个下载功能,根据系统跳转到不同的页面,如iphone跳转到IOS页面,android跳转到android页面. 下面为页面判断页面: <!DOCTYPE HTML> <h ...

  3. Spring配置文件外部化配置及.properties的通用方法

    摘要:本文深入探讨了配置化文件(即.properties)的普遍应用方式.包括了Spring.一般的.远程的三种使用方案. 关键词:.properties, Spring, Disconf, Java ...

  4. SecureCRT 使用技巧

    VanDyke CRT 和 VanDyke SecureCRT是最常用的终端仿真程序,简单的说就是windows下登录UNIX或Liunx服务器主机的软件.二者不同的是SecureCRT支持SSH∗( ...

  5. IOS版本被拒的经历

    IOS版本被拒的经历: 1,登陆方式依赖外部平台 因为我们的APP是只用微博登陆,想做成类似meerkat类型的,也能各种消息都同步微博. 结果当然行不通,这个确实是不听好人言,网上多个人都说过这个问 ...

  6. [转]jQuery Popup Login and Contact Form

    本文转自:http://www.formget.com/jquery-popup-form/ Pop up forms are the smart way to present your site. ...

  7. cnblogs美化及插件

    1.vp计数 http://www.amazingcounters.com 2.来源地图 http://clustrmaps.com 2.1来源地图 http://www.flagcounter.co ...

  8. Gnome创建桌面快捷方式

    Ctrl+Alt+T打开终端 输入gnome-desktop-item-edit 桌面/ --create-new (注: 桌面/ 要改为你桌面文件夹所在路径) 配置快捷方式属性,在“命令(A)”这行 ...

  9. 写一个iOS VoIP应用需要知道什么?

    IOS编程--VoIP解密 一般来说, IOS很少给App后台运行的权限. 仅有的方式就是 VoIP. IOS少有的为VoIP应用提供了后台socket连接,定期唤醒并且随开机启动的权限.而这些就是I ...

  10. [转载]ExtJs4 笔记(8) Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件

    作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)版权声明:本文的版权归作者与博客园共有.转载时须注明本文的详细链接,否则作者将保留追究其法律 ...