MVC三层架构搭建

项目主要是用三层来搭建项目,三层分为表现层,数据层和业务层。项目用了目前比较流行的IOC架构。目前流行的IoC 框架有AutoFac,Unity,Spring.NET等,项目中选用Spring.NET来搭建三层。

IOC简单介绍

IOC(Inversion of Control),中文译为控制反转,又称为“依赖注入”(DI =Dependence Injection)IOC的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器负责将这些联系在一起。网上有好多关于IOC介绍的文章,可以在网上查找关于IOC的知识。

三层搭建图

开始项目搭建

使用模块表为例,来搭建。表结构如下

解决方案项目设计:

1.新建一个空白解决方案名称为YCUniverse

2.在该解决方案下,新建解决方案文件夹业务层,网站层,数据层,业务层,基础层

3.网站层里面添加ASP.NET Web应用程序,项目选用MVC

4.数据层分为新建YCUniverse.DAL,YCUniverse.IDAL,YCUniverse.DALFactory类库

5.业务层分别新建YCUniverse.BLL,YCUniverse.IBLL类库

6.基础层新建YCUniverse.Model类库和YCUniverse.Ioc类库

建好后结构如下

基础层搭建

YCUniverse.Model作为实体类库,将EF模型实体添加到YCUniverse.Model类库

右键单击YCUniverse.Model类库=>添加=>新建项

选择好之后点击添加按钮

点击下一步进入下一步配置

点击完成按钮 完成EF的引用

将YCUniverse.Model类库中的App.Config 中链接数据库字符串复制到WebAppl网站Web.config文件中

数据层配置

YCUniverse.IDAL 类库添加YCUniverse.Model引用

在项目中每一张表都会涉及到查询,新增,删除,编辑,分页等操作,要是每一张表都要新建查询,删除,编辑,分页的方法,这样会增加项目开发时间和产生重复的代码。

解决方法将重复用到的方法封装成一个父类,当子类用到这些方法时可以继承父类。

1.新建父接口的类 名称为IBaseRepository.cs

public interface IBaseRepository<T> where T : class, new()
{
/// <summary>
/// 查询
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 添加
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
T AddEntity(T entity);
/// <summary>
/// 编辑
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool EditEntity(T entity);
/// <summary>
/// 删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool DelEntity(T entity);
/// <summary>
/// 分页
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="totalCount"></param>
/// <param name="whereLambda"></param>
/// <param name="orderByLambda"></param>
/// <param name="IsAsc"></param>
/// <returns></returns>
IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderByLambda, bool IsAsc);
}

2.新建模块表接口类 名称为ItbMenuRepository.cs继承父类IBaseRepository

public interface ItbMenuRepository : IBaseRepository<tbMenu>
{ }

YCUniverse.IDAL 类库配置完成

YCUniverse.DAL类库开始配置

YCUniverse.DAL类库添加YCUniverse.Model,YCUniverse.IDAL,YCUniverse.Ioc和EF引用

1.新建EF上下类FactoryDBContext.cs

public class FactoryDBContext
{
/// <summary>
/// 保证EF上下文实例是线程内唯一
/// </summary>
/// <returns></returns>
public static DbContext GetDBContext()
{
DbContext dbcontext = (DbContext)CallContext.GetData("dbcontext");
if (dbcontext == null)
{
dbcontext = new YCUniverseEntities();
CallContext.SetData("dbcontext", dbcontext);
}
return dbcontext;
}
}

2.新建父类BaseRepository.cs

public class BaseRepository<T> where T : class, new()
{
#region 1.0 获取ef上下文
public DbContext db = FactoryDBContext.GetDBContext();
#endregion #region 2.0 条件查询
public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda);
}
#endregion #region 3.0 分页
/// <summary>
/// 分页
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">页行数</param>
/// <param name="totalCount">总数</param>
/// <param name="whereLambda">条件lambda</param>
/// <param name="orderByLambda">排序lambda</param>
/// <param name="IsAsc">true 升序 falase 降序</param>
/// <returns></returns>
public IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderByLambda, bool IsAsc)
{
var temp = db.Set<T>().Where(whereLambda);
totalCount = temp.Count();
if (IsAsc)
{
temp = temp.OrderBy<T, s>(orderByLambda).Take<T>((pageIndex - ) * pageSize).Skip<T>(pageSize);
}
else
{
temp = temp.OrderByDescending<T, s>(orderByLambda).Take<T>((pageIndex - ) * pageSize).Skip<T>(pageSize);
}
return temp;
}
#endregion #region 4.0 添加
public T AddEntity(T entity)
{
db.Set<T>().Add(entity);
return entity;
}
#endregion #region 5.0 删除
public bool DelEntity(T entity)
{
db.Set<T>().Attach(entity);
db.Entry<T>(entity).State = EntityState.Deleted;
return true;
}
#endregion #region 6.0 编辑
public bool EditEntity(T entity)
{
db.Set<T>().Attach(entity);
db.Entry<T>(entity).State = EntityState.Modified;
return true;
}
#endregion
}

3.0 新建tbMenuRepositor.cs类继承BaseRepository

public class tbMenuRepositor : BaseRepository<tbMenu>, ItbMenuRepository
{
//自定义方法
}

YCUniverse.DAL类库配置完成

YCUniverse.Ioc配置

WebAppl添加YCUniverse.Ioc,Common.Logging.dll引用

在WebAppl网站Web.config中添加已下内容

<sectionGroup name="spring">
<!--跟下面Spring.Net节点配置是一一对应关系-->
<!--配置解析Spring块的对象-->
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
<!--配置解析Spring存放对象的容器集合-->
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup> <!--Spring.Net节点配置-->
<spring>
<context>
<!--容器配置-->
<!--<resource uri="config://spring/objects"/>-->
<!--xml文件方式,更改属性,复制到输出目录:始终复制-->
<resource uri="~/Config/dal.xml" />
<resource uri="~/Config/controllers.xml" />
<resource uri="~/Config/service.xml" />
</context>
</spring>
<!--log4net节点配置-->

YCUniverse.Ioc 类库添加Spring.Core.dll引用

新建SpringHelper.cs类

public class SpringHelper
{
#region Spring容器上下文 +IApplicationContext SpringContext
/// <summary>
/// Spring容器上下文
/// </summary>
private static IApplicationContext SpringContext
{
get
{
return ContextRegistry.GetContext();
}
}
#endregion #region 获取配置文件配置的对象 +T GetObject<T>(string objName) where T : class
/// <summary>
/// 获取配置文件配置的对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="objName"></param>
/// <returns></returns>
public static T GetObject<T>(string objName) where T : class
{
return (T)SpringContext.GetObject(objName); }
#endregion
}

YCUniverse.Ioc配置完成

在YCUniverse.IDAL类库添加接口类IDBSession.cs

public interface IDBSession
{
bool SaveChange();
ItbMenuRepository ItbMenuRepository { get; set; }
}

YCUniverse.DALFactory类库配置

引用YCUniverse.Model,YCUniverse.IDAL,YCUniverse.DAL,EF

1.在YCUniverse.DAL中新建DalFactory.cs

public class DalFactory
{
public static ItbMenuRepository GettbMenuRepository
{
get
{
return SpringHelper.GetObject<ItbMenuRepository>("tbMenuRepository");
}
}
}

2.新建DBSession.cs

public class DBSession : IDBSession
{
private ItbMenuRepository _tbMenuRepository;
public ItbMenuRepository ItbMenuRepository
{
get
{
if (_tbMenuRepository == null)
{
_tbMenuRepository = DalFactory.GettbMenuRepository;
}
return _tbMenuRepository;
} set
{
_tbMenuRepository = value;
}
} DbContext db = FactoryDBContext.GetDBContext();
public bool SaveChange()
{
return db.SaveChanges() > ;
}
}

3.新建FactoryDBSession.cs

public class FactoryDBSession
{
/// <summary>
/// 实例化DBSession
/// </summary>
/// <returns></returns>
public static IDBSession GetDBSession()
{
DBSession dbsession = (DBSession)CallContext.GetData("dbsession");
if (dbsession == null)
{
dbsession = new DBSession();
CallContext.SetData("dbsession", dbsession);
}
return dbsession;
}
}

YCUniverse.DALFactory类库配置完成

YCUniverse.IBLL类库开始配置

引用YCUniverse.Model,YCUniverse.IDAL,YCUniverse.DAL和YCUniverse.DALFactory

1.新建父类IBaseService.cs

public interface IBaseService<T> where T : class, new()
{
IBaseRepository<T> CurrentRepository { get; set; }
IDBSession GetCurrentDbSession { get; }
IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderByLambda, bool IsAsc);
T AddEntity(T entity);
bool EditEntity(T entity);
bool DelEntity(T entity);
}

2.新建ItbMenuService.cs

public interface ItbMenuService : IBaseService<tbMenu>
{
//自定义方法
}

YCUniverse.IBLL类库配置完成

YCUniverse.BLL类库开始配置

引用YCUniverse.Model,YCUniverse.IDAL,YCUniverse.DAL,YCUniverse.IBLL和YCUniverse.DALFactory

1.新建父类BaseService.cs

public abstract class BaseService<T> where T : class, new()
{
public IBaseRepository<T> CurrentRepository { get; set; }
public IDBSession GetCurrentDbSession
{
get
{
return FactoryDBSession.GetDBSession();
}
}
public abstract void SetCurretnRepository();
public BaseService()
{
SetCurretnRepository();
} #region 添加
public T AddEntity(T entity)
{
CurrentRepository.AddEntity(entity);
GetCurrentDbSession.SaveChange();
return entity;
}
#endregion #region 删除
public bool DelEntity(T entity)
{
CurrentRepository.DelEntity(entity);
return GetCurrentDbSession.SaveChange();
}
#endregion #region 编辑
public bool EditEntity(T entity)
{
CurrentRepository.EditEntity(entity);
return GetCurrentDbSession.SaveChange();
}
#endregion #region 条件查询
public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
{
return CurrentRepository.LoadEntities(whereLambda);
}
#endregion #region 分页
public IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, s>> orderByLambda, bool IsAsc)
{
return CurrentRepository.LoadPageEntities<s>(pageIndex, pageSize, out totalCount, whereLambda, orderByLambda, IsAsc);
}
#endregion }

2.新建tbMenuService.cs继承父类

public class tbMenuService : BaseService<tbMenu>, ItbMenuService
{
public override void SetCurretnRepository()
{
CurrentRepository = this.GetCurrentDbSession.ItbMenuRepository;
}
}

YCUniverse.BLL配置完成

网站层 WebAppl配置

引用YCUniverse.Model,YCUniverse.BLL和YCUniverse.IBLL

新建文件夹Config

分别新建controllers.xml,dal.xml,service.xml设置3个文件的属性为始终复制

dal.xml

<objects xmlns="http://www.springframework.net">
<!--这里放容器里面的所有节点-->
<description>An example that demonstrates simple IoC features.</description>
<!--name 必须要唯一的,type=类的全名称,所在的程序集-->
<object name="tbMenuRepository" type="YCUniverse.DAL.tbMenuRepositor, YCUniverse.DAL" singleton="false"></object>
</objects>

service.xml

<objects xmlns="http://www.springframework.net">
<!--这里放容器里面的所有节点-->
<!--name 必须要唯一的,type=类的全名称,所在的程序集-->
<object type="YCUniverse.BLL.tbMenuService, YCUniverse.BLL" singleton="false" name="tbMenuService"></object>
</objects>

controllers.xml

<objects xmlns="http://www.springframework.net">
<!--这里放容器里面的所有节点-->
<!--name 必须要唯一的,type=类的全名称,所在的程序集-->
<!--属性注入-->
<!--权限管理-->
<object type="WebAppl.Controllers.BaseController, WebAppl" singleton="false" >
<property name="tbMenuService" ref="tbMenuService" />
</object>
</objects>

在控制器中新建类BaseController.cs

public class BaseController : Controller
{
//属性注入
public ItbMenuService tbMenuService
{
get
{
return SpringHelper.GetObject<ItbMenuService>("tbMenuService");
}
}
}

到此三层架构搭建完成

新建页面测试

新建TestController控制器

运行项目 页面如下所示

项目源代码地址 提取码 ky97

视频地址提取码: 7wuu

  

MVC三层架构搭建的更多相关文章

  1. MVC三层架构编程(Dao、service、servlet 之间的关系)

    木哈哈~先开心一会儿,人生的第一篇博客aaa.我一定好好写.不过之前也没怎么看别人写过,还是有点小激动呢,加油.好好总结,会总结的宝宝才会有提高! 今天想总结一下mvc三层架构模型编程,宝宝学习不怎么 ...

  2. Angular JS从入门基础 mvc三层架构 常用指令

    Angular JS从入门基础  mvc模型 常用指令 ★ 最近一直在复习AngularJS,它是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核心 ...

  3. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  4. 三层架构搭建(asp.net mvc + ef)

    第一次写博客,想了半天先从简单的三层架构开始吧,希望能帮助到你! 简单介绍一下三层架构, 三层架构从上到下分:表现层(UI),业务逻辑层(BLL),数据访问层(DAL)再加上数据模型(Model),用 ...

  5. Asp.Net MVC三层架构之autofac使用教程

    开发环境:vs2015..net4.5.2.mvc5.ef6 Autofac简介 IOC控制反转(Inversion of Control,缩写为IOC),Autofac是一个开源的依赖注入框架,Au ...

  6. mvc项目架构搭建之UI层的搭建

    项目架构搭建之UI层的搭建 Contents 系列一[架构概览] 0.项目简介 1.项目解决方案分层方案 2.所用到的技术 3.项目引用关系 系列二[架构搭建初步] 4.项目架构各部分解析 5.项目创 ...

  7. MVC三层架构模式编程思想 JSP-Servlet-JavaBean

    MVC(Mdodel-View-Controller)编程模式.把一个Java应用分成三层:模型层.视图层.控制层,各层分别实现各层的功能,整个过程见下图就一目了然了. watermark/2/tex ...

  8. MVC——三层架构笔记、1

    三层架构MVC笔记1. DAL——数据访问层:(专门与数据库交互,增删查改的方法都在这:需引用MODEL层) BLL——业务逻辑层:(页面与数据库之间的桥梁:需引用DAL.MODEL层) MODEL— ...

  9. MVC三层架构

    需求: 注册登录: # 知识补充: >> MVC模型: |-- M 模型: |-- V 视图: |-- >> 基本概念: |-- 层级之间的调用关系: |-- V层接收前台数据 ...

随机推荐

  1. selenium设置user-agent以及对于是否是浏览器内核进行反爬

    (Session info: chrome=75.0.3770.90),不同版本方法可能会有些不同 推荐查资料网站必应可以避开一堆广告 一.user-agent设置 from selenium imp ...

  2. IOS中的深拷贝和浅拷贝

    标签: 什么是深拷贝?什么是浅拷贝? 为什么经常看到字符串属性要这样定义,那个copy是神马意思? @property(nonatomic,copy)NSString* name; 为什么下面的写法是 ...

  3. 【转载】Android 的 Handler 机制实现原理分析

    handler在安卓开发中是必须掌握的技术,但是很多人都是停留在使用阶段.使用起来很简单,就两个步骤,在主线程重写handler的handleMessage( )方法,在工作线程发送消息.但是,有没有 ...

  4. 网络爬虫之使用pyppeteer替代selenium完美绕过webdriver检测

    1引言 曾经使用模拟浏览器操作(selenium + webdriver)来写爬虫,但是稍微有点反爬的网站都会对selenium和webdriver进行识别,网站只需要在前端js添加一下判断脚本,很容 ...

  5. Mysql—存储引擎详解

    存储引擎基本操作 查看数据库支持的所有的存储引擎 mysql> show engines; 查看数据库目前使用的引擎 mysql> show varlables like "%s ...

  6. Node.js—基本知识

    一.第一个Node代码 1. 运行Node.js   通过node E:\Node代码\hello.js运行代码:Node.js是服务器的程序,写的js语句都将运行在服务器上.返回给客户的,都是已经处 ...

  7. 自定义vue的loading插件

    在一般的vue项目中,都会用到Loading或者Alert之类的弹窗浮层,而他们是一种比较高频率出现的组件. 一般情况下,我们都会去直接import该组件,然后直接以标签的形式引用进去当前页面组件中, ...

  8. Pwnable-leg

    Download : http://pwnable.kr/bin/leg.c Download :http://pwnable.kr/bin/leg.asm 友链 https://blog.csdn. ...

  9. TransportFireWall

    1.shadow for python install on windows (1.) install python pip (2.) install openssl for windows (3.) ...

  10. LG4824 「USACO2015FEB」(Silver)Censoring KMP+栈

    问题描述 LG4824 题解 大概需要回顾(看了题解) KMP 先对要删除的 模式串 进行自我匹配,求出 \(\mathrm{fail}\) 然后再扫 文本串 的过程中记录一下每个字符匹配的最大长度, ...