ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑层的封装
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑层的封装
ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 (2):数据库访问层的设计Demo (3):面向接口编程
前言:前面几篇博客我们基本已经介绍完了搭建整个项目和数据库访问层以及一些业务逻辑层的实现,当然了,我们的数据库访问层这样还是可以在进行封装的,但是我到这里就行了吧,项目也不大,不需要那么麻烦的,那么我们今天开始介绍我们需要介绍的内容,那就是我们对业务逻辑的封装,这个博客如果大家要看的话,我建议从第一张开始看是最容易理解的,废话不多说了,我们直接切入主题。
1. 初步设计业务逻辑层
(1) 从昨天我们对LYZJ.UserLimitMVC.BLL类库的操作,我们在这个类库下面添加了UserInfoService,那么其他的实体对象也是有Service,那么这时候又是重复性的动作,UserInfo含有操作数据库的所有方法,Role也含有操作数据库的方法,其他的表一样,那么我们怎么办呢,当然就是封装了,这时候我们就需要建立一个基类来实现这个动作。
(2) 首先我们在昨天的基础上面添加两个类,我们在LYZJ.UserLimitMVC.BLL类库下面再添加一个RoleService类,BaseService类。
2.基类BaseService的分析
(1)首先BaseService类肯定是一个泛型,限制其继承自类,这里面就会实现相应的增删改查的方法。
(2)那么这时候我先将BaseService的一部分代码帖上来,然后进行讲解,想必如果开发过这类项目的人都知道这块的使用,但是下面我还是解释一下,解释的不太好,完全是自己的语言,如果谁会解释的更好,希望能够给我留言,我将非常感谢。
namespace LYZJ.UserLimitMVC.BLL
{
public abstract class BaseService<T> where T : class, new()
{
public IDAL.IBaseRepository<T> CurrentRepository { get; set; }
//基类的构造函数
public BaseService()
{
SetCurrentRepository(); //构造函数里面去调用了,此设置当前仓储的抽象方法
} //约束
public abstract void SetCurrentRepository(); //子类必须实现 public T AddEntity(T entity)
{
//调用T对应的仓储来做添加工作
return CurrentRepository.AddEntity(entity);
}
}
}
(3)下面就是我对上面代码的分析
首先写了方法Public T AddEntity(){return CurrentRepository.AddEntity(entity);},那么当我们对实体进行添加的时候,我们首先需要调用T对应的数据库访问层来调用相应的Entity方法,我们在昨天写UserInfoService的时候,我们是直接调用了UserInfoRepository(仓储)的Entity方法,但是现在我们在UserInfoService中的代码都要放到基类中去实现,那么基类中的T对应的是那个数据库访问层的仓储我们是不知道的,那么我们怎么办呢?
不要慌,我们仔细分析代码的话我们会发现解决之法,现在T对应的仓储是谁呢?我们需要在方法里面调用来实现添加工作,现在首先假设我们知道我们T对应的仓储叫CurrentRepository,我们只需要将entity参数传递给方法即可CurrentRepository.AddEntity(entity);,但是假设是假设,还是不成立的,但是这时候这就是我们的思想,我们已经知道这样可以解决,所以我们只需要找到解决的办法即可。
当前在我们基类中T对应的仓储是谁我们不知道,这里可以使用反射来实现,但是我这里就不这么做了,既然我们基类不知道T对应的仓储是谁?那么我们子类肯定T对应的仓储是谁,因为子类对应的就是实体,所以这时候我们有办法了,这时候我们只需要让子类来设置这个属性的实例不就完事了吗,这时候我们在基类下面写入一个属性,注意:我们当前仓储可能针对的是所有的表的仓储,那么我们这样写:public abstract void SetCurrentRepository();,那麽下面我们调用接口的属性就完事了。
这时候我们就想这里我们为什么要这么写呢?因为当前仓储可能指向任何一个仓储,有可能指向UserInfo仓储,也有可能指向RoleInfo仓储等,那么这里我们使用IDAL.IBaseRepositroy完全可以,因为当你仔细看我花的那张图的时候就看到了仓储基本都间接地继承自IBaseRepository仓储,那麽我们使用IBase仓储接收当前的仓储是没有任何问题的。
关键当我们这么定义的时候CurrentRepository是null,这时候我们下面方法如果调用的话可能会报出异常,那么在调用这个方法之前我们必须为CurrentRepository属性赋值,那麽给这个属性赋值在哪里比较合适呢,我想到了构造方法,构造方法给这个属性赋值最合适,在这当前我们基类中也不知道CurrentRepository赋什么值,只有子类中才知道,这时候父类就想让子类给这个属性赋值,那麽怎么办呢?我们定义一个抽象方法,当我们定义抽象方法的时候我们的类也要改成抽象的,抽象方法如下:public abstract void SetCurrentRepository(); ,这个抽象方法子类必须实现,在这里我在构造函数里面再去调用这个抽象方法。
在基类里面的构造函数调用父类的纯的抽象方法,那麽经过多态的话最终调用方法的时候去执行子类里面的仓储。
到这里我关于业务逻辑层的基类解释已经完成了,个人感觉语言真心组织的不好,如果哪位看不懂或者怎么的,可以加群,我们在共同探讨一下,到这里我们的LYZJ.UserLimitMVC.BLL类库完成了
3. LYZJ.UserLimitMVC.BLL类库的源代码
(1)因为这个类库的实现我已经在上面讲玩了,所以这里不累赘的再说了,下面我直接贴最后的代码,大家可以参考一下。
(2)BaseService.CS
namespace LYZJ.UserLimitMVC.BLL
{
public abstract class BaseService<T> where T : class, new()
{
public IDAL.IBaseRepository<T> CurrentRepository { get; set; }
//基类的构造函数
public BaseService()
{
SetCurrentRepository(); //构造函数里面去调用了,此设置当前仓储的抽象方法
}
public abstract void SetCurrentRepository(); //子类必须实现
//实现对数据库的添加功能
public T AddEntity(T entity)
{
//调用T对应的仓储来做添加工作
return CurrentRepository.AddEntity(entity);
}
//实现对数据的修改功能
public bool UpdateEntity(T entity)
{
return CurrentRepository.UpdateEntity(entity);
}
//实现对数据库的删除功能
public bool DeleteEntity(T entity)
{
return CurrentRepository.DeleteEntity(entity);
}
//实现对数据库的查询 --简单查询
public IQueryable<T> LoadEntities(Func<T, bool> whereLambda)
{
return CurrentRepository.LoadEntities(whereLambda);
}
/// <summary>
/// 实现对数据的分页查询
/// </summary>
/// <typeparam name="S">按照某个类进行排序</typeparam>
/// <param name="pageIndex">当前第几页</param>
/// <param name="pageSize">一页显示多少条数据</param>
/// <param name="total">总条数</param>
/// <param name="whereLambda">取得排序的条件</param>
/// <param name="isAsc">如何排序,根据倒叙还是升序</param>
/// <param name="orderByLambda">根据那个字段进行排序</param>
/// <returns></returns>
public IQueryable<T> LoadPageEntities<S>(int pageIndex, int pageSize, out int total, Func<T, bool> whereLambda,
bool isAsc, Func<T, S> orderByLambda)
{
return CurrentRepository.LoadPageEntities(pageIndex, pageSize, out total, whereLambda, isAsc, orderByLambda);
}
}
}
(3)UserInfoService.cs
namespace LYZJ.UserLimitMVC.BLL
{
/// <summary>
/// UserInfo业务逻辑
/// </summary>
public class UserInfoService:BaseService<UserInfo>
{
public override void SetCurrentRepository()
{
CurrentRepository = DAL.RepositoryFactory.UserInfoRepository;
}
//访问DAL实现CRUD
//private DAL.UserInfoRepository _userInfoRepository = new UserInfoRepository();
//依赖接口编程
//private IUserInfoRepository _userInfoRepository = new UserInfoRepository();
//private IUserInfoRepository _userInfoRepository = RepositoryFactory.UserInfoRepository;
//public UserInfo AddUserInfo(UserInfo userInfo)
//{
// return _userInfoRepository.AddEntity(userInfo);
//}
//public bool UpdateUserInfo(UserInfo userInfo)
//{
// return _userInfoRepository.UpdateEntity(userInfo);
//}
}
}
(4)RoleService.cs
namespace LYZJ.UserLimitMVC.BLL
{
public class RoleService:BaseService<Role>
{
//重写抽象方法,设置当前仓储为Role仓储
public override void SetCurrentRepository()
{
//设置当前仓储为Role仓储
CurrentRepository = DAL.RepositoryFactory.RoleRepository;
}
}
}
4.业务逻辑接口层
(1)那麽我们业务逻辑层需不要一个接口层呢?我觉得需要,为什么呢?因为我们涉及到层与层之间的调用了,UI层调用业务逻辑层,我们一定要依赖接口来编程。那麽下面我们来实现业务逻辑接口层,这个和数据访问接口层的作用基本一致。
(2)首先我们添加一个类库LYZJ.UserLimitMVC.IBLL,用来实现对于业务逻辑接口层的封装,然后我们新建三个接口:IUserInfoService,IRoleService,IBaseService。我们需要给这个类库添加Model层的引用。下面我们写出这三个接口层的代码,我这里就不解释了,和前面的意思都差不多。
(3) IBaseService接口
namespace LYZJ.UserLimitMVC.IBLL
{
public interface IBaseService<T> where T:class ,new ()
{
// 实现对数据库的添加功能,添加实现EF框架的引用
T AddEntity(T entity);
//实现对数据库的修改功能
bool UpdateEntity(T entity);
//实现对数据库的删除功能
bool DeleteEntity(T entity);
//实现对数据库的查询 --简单查询
IQueryable<T> LoadEntities(Func<T, bool> whereLambda);
/// <summary>
/// 实现对数据的分页查询
/// </summary>
/// <typeparam name="S">按照某个类进行排序</typeparam>
/// <param name="pageIndex">当前第几页</param>
/// <param name="pageSize">一页显示多少条数据</param>
/// <param name="total">总条数</param>
/// <param name="whereLambda">取得排序的条件</param>
/// <param name="isAsc">如何排序,根据倒叙还是升序</param>
/// <param name="orderByLambda">根据那个字段进行排序</param>
/// <returns></returns>
IQueryable<T> LoadPageEntities<S>(int pageIndex, int pageSize, out int total, Func<T, bool> whereLambda,
bool isAsc, Func<T, S> orderByLambda);
}
}
(4) IUserInfoService接口
namespace LYZJ.UserLimitMVC.IBLL
{
public interface IUserInfoService:IBaseService<UserInfo>
{
}
}
(5) IRoleService接口
namespace LYZJ.UserLimitMVC.IBLL
{
public interface IRoleService:IBaseService<Role>
{
}
}
5.对业务逻辑层的再次修改
(1)当我们实现完业务逻辑接口层的时候,我们就需要让BLL去实现这个接口,我们给BLL的类库添加IBLL的引用,然后让UserInfoService,RoleService实现各自的继承关系,我这里就只贴出RoleService的代码,其他的都一样。
namespace LYZJ.UserLimitMVC.BLL
{
public class RoleService:BaseService<Role>,IRoleService
{
//重写抽象方法,设置当前仓储为Role仓储
public override void SetCurrentRepository()
{
//设置当前仓储为Role仓储
CurrentRepository = DAL.RepositoryFactory.RoleRepository;
}
}
}
6.小结
(1)到这里我们今天的业务逻辑层完成了,从今天开始,我们这个Demo的后台涉及已经全部完成,我们明天开始涉及其前台页面。今天的这篇文章本人感觉写的也不是很好,重点是语言太难组织,灵活性太大,所以需要看此博客的博友们我建议从第一篇博客看起,那麽就能很容易的理解这些讲的是什么。
(2)整体框架层图纸

(3)最终的Demo项目架构图

项目下载:明天晚上我会将项目上传,希望大家关注,谢谢!
Kencery返回本系列开篇
ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑层的封装的更多相关文章
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1)框架搭建 前言:这 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列
http://www.cnblogs.com/hanyinglong/archive/2013/03/22/2976478.html ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇 前言:博客又有一段时间没有更新了,心里感觉这段时间空空的,好像什么都没有学下,所以就想写博客,所以就有了这个系列,这里当然也 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(21)-用户角色权限基本的实现说明 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(19)-用户信息的修改和浏览
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(19)-用户信息的修改和浏览 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(18)-过滤器的使用和批量删除数据(伪删除和直接删除)
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(18)-过滤器的使用和批量删除数据(伪删除和直接删除) ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证)
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证) ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框 ...
随机推荐
- Java引用类型变量
Java引用类型变量 1.编译时类型:由声明该变量时使用的类型决定 2.执行时类型:由实际赋给该变量的对象决定 类型不一致的假设编译时类型和执行,可能会出现多态性 版权声明:本文博主原创文章.博 ...
- mtk硬件项目开始关闭蓝牙功能:mtk 硬件ScanCode和keycode应用演示示例
项目要求:该项目因为没有使用android5.0,导致启动bluetooth的蓝牙audio slave功能必须使用第三方模组,该第三方模组,启动是通过android主板通过GPIO控制.UI界面是通 ...
- HDU 4508 沼泽湿地系列故事——记住减肥I (2013腾讯编程马拉松预赛第一)
pid=4508">http://acm.hdu.edu.cn/showproblem.php?pid=4508 题目大意: 给定一些数据. 每组数据以一个整数n開始,表示每天的食物清 ...
- JAVA字符串格式化-String.format()使用
传统型格类型 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象. 熟悉C语言的同学应该记得C语言的sprintf()方法.两者有类似之处.format()方法有两种重载 ...
- UML 简单的总结
上某一个地方,总有个记忆挥不散,每一个深夜某一个地方,总有着最深的思量- 都说岁月无情人有情,记忆easy催人老,可有时候反倒觉着人比岁月更无情.岁月留下了我们成长的印记,但是有时候以前认为会相伴永远 ...
- JAVA Metrics 度量工具使用介绍1
Java Metric使用介绍1 Metrics是一个给JAVA提供度量工具的包,在JAVA代码中嵌入Metrics代码,可以方便的对业务代码的各个指标进行监控,同一时候,Metrics可以非常好的跟 ...
- SpringMVC源码解析- HandlerAdapter - ModelFactory(转)
ModelFactory主要是两个职责: 1. 初始化model 2. 处理器执行后将modle中相应参数设置到SessionAttributes中 我们来看看具体的处理逻辑(直接充当分析目录): 1 ...
- Android ELF文件格式
最近一直在学习elf相关信息.一个小总结,这里记录,也方便以后查阅. ELF是类Unix类系统,当然也包含Android系统上的可运行文件格式(也包含.so和.o类文件). 能够理解为Android系 ...
- OpenGL学习日记-2015.3.13——多实例渲染
实例化(instancing)或者多实例渲染(instancd rendering)是一种连续运行多条同样渲染命令的方法.而且每一个命令的所产生的渲染结果都会有轻微的差异. 是一种很有效的.有 ...
- Android4.0 Design之UI设计缺陷1
我想成为Android卓越发展project联赛,不知道Android它如何设计规则,Android4.0谷歌公司的问世后Android一系列的设计原则,程序猿规范,不要盲目模仿IOS它的设计,由于A ...