为什么要自己搭框架?

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

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

要花费不少时间。

所以我才有了搭建自己的框架的想法,我的框架用到了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. 【mysql】统计库、表大小

    1. 查看该数据库实例下所有库大小,得到的结果是以MB为单位 mysql> select table_schema,sum(data_length)/1024/1024 as data_leng ...

  2. 问题解决——Win7 64 安装 AutoCAD 2010 32位 和 清华天河PC CAD

    最近单位组了一台电脑,配置还好,E3大法+R9 280,装了Win7 64位系统. ========================================================== ...

  3. python代码学习day03-序列化学习pickle及json

    #!/usr/bin/env python #coding:utf8 import pickle,json import datetime dic1 = {'name':'alex', 'age':4 ...

  4. jenkins 更换主数据目录

    工作中,由于Jenkins默认的主目录空间太小,导致需要将Jenkins默认的主目录修改到其它目录.本文针对更改Jenkins的主目录详细介绍. 注意:在Jenkins运行时是不能更改的. 请先将Je ...

  5. js删除所有子元素

    没有removeAll的API,但也十分容易实现: var lis = $("#yetai_tbody").find("tr"); $(lis).each(fu ...

  6. ext3,ext4,xfs和btrfs文件系统性能对比

    应为原文:http://www.ilsistemista.net/index.php/linux-a-unix/6-linux-filesystems-benchmarked-ext3-vs-ext4 ...

  7. [转]后台页面访问权限:页面基类&内置票据认证 使用方法

    本文转自:http://www.cnblogs.com/fishtreeyu/archive/2011/01/29/1947421.html 一般网站后台页面除了登录页面login.aspx未登录用户 ...

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

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

  9. [C#] 委托之Action和Func区别

    一.说明 一般我们定义委托都是有如下两步: public delegate void MyDelegate(string name);//定义委托 public MyDelegate myDelega ...

  10. android stuio eclipse映射下的快捷键

    转:关于 android stuio eclipse映射下的快捷键 http://www.cnblogs.com/0616--ataozhijia/p/3870064.html 会持续更新)这边讲的常 ...