WedeNet2018.BussinessLogic-业务逻辑层:
结构如下:

基类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WedeNet2018.Infrastructure;
using WedeNet2018.Infrastructure.Components; namespace WedeNet2018.BussinessLogic
{
/// <summary>
/// 业务逻辑层父类
/// </summary>
public abstract class AbsBussinessLogic
{
public AbsBussinessLogic()
{
} /// <summary>
/// 接受一个实现了IUnitOfWorks接口的工作单元实例
/// </summary>
protected IUnitOfWorks _works { get; set; } /// <summary>
/// 当前工作单元的提交方法,可在子类中重写。
/// </summary>
/// <returns></returns>
public virtual int Commit()
{
return _works.Commit();
}
}
}

这个基类的目的主要是实现UnitOfWorks的事务性提交,对于具体业务性的操作放在派生类中。当应用层调用不同的BussinessLogic进行对应的业务处理完毕后,可调用该数据上下文对应的UnitOfWorks实例的Commit()方法统一提交。

实现类如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WedeNet2018.Infrastructure;
using WedeNet2018.Infrastructure.Components; namespace WedeNet2018.BussinessLogic
{
public class OrdersBussinessLogic : AbsBussinessLogic
{
public OrdersBussinessLogic(IWedeUnitOfWorks works)
{
_works = works;
} public IQueryable<Orders> GetOrders(int orderType){
IQueryable<Orders> ret = null;
ret = _works.All<Orders>().Where(r=>r.OrderType.Equals(orderType)); return ret;
} public void Add(Orders order) {
_works.Add<Orders>(order);
} public Orders Find(int id) {
Orders order = _works.Find<Orders>(id);
return order;
} public void Update(Orders order)
{
_works.Update<Orders>(order);
} public void Delete(int id)
{
Orders order = _works.Find<Orders>(id);
_works.Delete<Orders>(order);
}
}
}

异常处理
系统异常(不论是预期的或非预期的)都要抛至业务逻辑层为止,业务层对捕获的异常进行处理。
规则为:
1、使用RealProxy动态织入业务层指定的方法;
2、自定义异常类和Attribute;
3、业务逻辑层以下发生的异常层层上抛至业务逻辑层,并且要日志记录异常发生具体信息;
4、业务逻辑层捕获到下层抛出的异常后可以区分是预期异常还是非预期异常;
5、如果全局异常处理器捕获到了非预期的异常,则统一抛出“未知错误”;
6、可以对捕获的异常再次处理返给客户端;

业务层实现代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WedeNet2018.Common;
using WedeNet2018.Common.Attributes;
using WedeNet2018.Common.Exceptions;
using WedeNet2018.Infrastructure;
using WedeNet2018.Infrastructure.Components;
using WedeNet2018.Infrastructure.Components.aop; namespace WedeNet2018.BussinessLogic
{
public class OrdersBussinessLogic : AbsBussinessLogic
{
public OrdersBussinessLogic(IWedeUnitOfWorks works)
{
log = LoggerHelper.WedeNetLogger;
//_works = works; #region AOP动态织入
var dynamicProxy = new DynamicProxy<IWedeUnitOfWorks>(works);
dynamicProxy.BeforeExecute += (s, e) =>
{
log.Info(e.MethodName + "方法执行前");
};
dynamicProxy.AfterExecute += (s, e) =>
{
log.Info(e.MethodName + "方法执行后");
};
dynamicProxy.ErrorExecuting += (s, e) =>
{
log.Info(e.MethodName + "方法执行异常");
Type t = works.GetType();
//标注了[CustomFilter]注解的IUnitOfWorks类全局异常处理才生效
if (t.IsDefined(typeof(CustomFilterAttribute), false))
{
throw new CustomException(dynamicProxy.MyException.Message,
dynamicProxy.MyException.InnerException);
} };
//过滤不需要织入的方法
dynamicProxy.Filter = m => (!m.Name.StartsWith("Get") || !m.Name.StartsWith("Find"));
_works = dynamicProxy.GetTransparentProxy() as IWedeUnitOfWorks;
#endregion
} public IQueryable<Orders> GetOrders(int orderType){
IQueryable<Orders> ret = null;
try
{
ret = _works.All<Orders>().Where(r => r.OrderType.Equals(orderType));
}
catch (Exception ex)
{
#region 异常处理
if (ex is CustomException)
{
log.Info("自定义异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
else
{
log.Info("未知异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
#endregion
}
return ret;
} public bool Add(Orders order) {
try
{
_works.Add<Orders>(order);
return true;
}
catch (Exception ex) {
#region 异常处理
if (ex is CustomException)
{
log.Info("自定义异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
else
{
log.Info("未知异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
#endregion
return false;
}
} public Orders Find(int id) {
Orders order = _works.Find<Orders>(id);
return order;
} public bool Update(Orders order)
{
try
{
_works.Update<Orders>(order);
return true;
}
catch (Exception ex)
{
#region 异常处理
if (ex is CustomException)
{
log.Info("自定义异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
else
{
log.Info("未知异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
#endregion
return false;
}
} public bool Delete(int id)
{ Orders order = _works.Find<Orders>(id);
try
{
_works.Delete<Orders>(order);
return true;
}
catch (Exception ex)
{
#region 异常处理
if (ex is CustomException)
{
log.Info("自定义异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
else
{
log.Info("未知异常:" + ex.Message);
if (ex.InnerException != null)
{
log.Info(ex.InnerException.Message + "发生于" + ex.InnerException.TargetSite.ReflectedType + "类的" + ex.InnerException.TargetSite.Name + "方法。");
}
}
#endregion
return false;
}
} }
}

动态代理代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.Text;
using System.Threading.Tasks; namespace WedeNet2018.Infrastructure.Components.aop
{
public class DynamicProxy<T> : RealProxy
{
private readonly T _decorated;
private Predicate<MethodInfo> _filter;
public event EventHandler<IMethodCallMessage> BeforeExecute;
public event EventHandler<IMethodCallMessage> AfterExecute;
public event EventHandler<IMethodCallMessage> ErrorExecuting;
public DynamicProxy(T decorated)
: base(typeof(T))
{
_decorated = decorated;
Filter = m => true;
}
public Predicate<MethodInfo> Filter
{
get { return _filter; }
set
{
if (value == null)
_filter = m => true;
else
_filter = value;
}
}
private void OnBeforeExecute(IMethodCallMessage methodCall)
{
if (BeforeExecute != null)
{
var methodInfo = methodCall.MethodBase as MethodInfo;
if (_filter(methodInfo))
BeforeExecute(this, methodCall);
}
}
private void OnAfterExecute(IMethodCallMessage methodCall)
{
if (AfterExecute != null)
{
var methodInfo = methodCall.MethodBase as MethodInfo;
if (_filter(methodInfo))
AfterExecute(this, methodCall);
}
}
private void OnErrorExecuting(IMethodCallMessage methodCall, Exception ex)
{
if (ErrorExecuting != null)
{
this.MyException = ex;
var methodInfo = methodCall.MethodBase as MethodInfo;
if (_filter(methodInfo))
ErrorExecuting(this, methodCall);
}
} public Exception MyException
{
get;
set;
} public override IMessage Invoke(IMessage msg)
{
var methodCall = msg as IMethodCallMessage;
var methodInfo = methodCall.MethodBase as MethodInfo;
OnBeforeExecute(methodCall);
try
{
var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
OnAfterExecute(methodCall);
return new ReturnMessage(
result, null, 0, methodCall.LogicalCallContext, methodCall);
}
catch (Exception e)
{
//CustomException customException = null; Exception ex = null;
//if (typeof(T).IsDefined(typeof(CustomFilterAttribute), true)) {
// customException = new CustomException(e.Message, e.InnerException);
//}
//if (customException != null)
// ex = customException;
//else
// ex = e; OnErrorExecuting(methodCall, e);
return new ReturnMessage(e, methodCall);
}
} }
}

搭建自己的框架WedeNet(三)的更多相关文章

  1. 搭建自己的框架WedeNet(五)

    WedeNet2018.WedeWcfServices-WCF服务层:结构如下: 就是定义了服务契约接口和服务类,以OrderServices为例,如下: using System; using Sy ...

  2. 搭建自己的框架WedeNet(四)

    WedeNet2018.Web-UI层:结构如下: 首先,在Controller中定义BaseController,以便加入统一处理逻辑,如下: using log4net; using System ...

  3. 搭建自己的框架WedeNet(一)

    框架用到的技术: EF.UnitOfWork+Repository.Ninject.log4net.WCF.MVC.T4.windows服务.AOP前端技术:Bootstrap.layer.jQuer ...

  4. 搭建自己的框架WedeNet(二)

    WedeNet2018.Infrastructure-基础设施层:结构如下: Tools结构如下: 考虑到系统可能会有多个数据上下文(暂时以两个为例),所以根据需要定义两个T4模板用来生成对应的ent ...

  5. 如何搭建MVC + EF 框架

    1.搭建MVC框架 1.1 VS2010:需要安装WPI 安装 ASP.NET MVC 4 和Visual Studio 2010 系统必备组件 如果上述链接无法打开,请访问:http://www.a ...

  6. Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED

    Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED Xvfb+YSlow+ShowSlow搭建前端性能测试框架 作者:黑三 | 时间:2010-07-07 ...

  7. Windows环境搭建Web自动化测试框架Watir

    Windows环境搭建Web自动化测试框架Watir 一.前言     Web自动化测试一直是一个比较迫切的问题,对于现在web开发的敏捷开发,却没有相对应的敏捷测试,故开此主题,一边研究,一边将We ...

  8. 搭建App主流框架_纯代码搭建(OC)

    转载自:http://my.oschina.net/hejunbinlan/blog/529778?fromerr=EmSuX7PR 搭建主流框架界面 源码地址在文章末尾 达成效果 效果图 注:本文部 ...

  9. 【微服务】使用spring cloud搭建微服务框架,整理学习资料

    写在前面 使用spring cloud搭建微服务框架,是我最近最主要的工作之一,一开始我使用bubbo加zookeeper制作了一个基于dubbo的微服务框架,然后被架构师否了,架构师曰:此物过时.随 ...

随机推荐

  1. vs下qt的信号与槽实现

    实现主窗口中Add按钮的功能, 这一部分要特别注意,除了实现功能代码外,还需自己手动添加一些其他的代码(Qt Creator可以自动添加). 我们需要在2个地方添加代码. 第1个是在addressbo ...

  2. 【8583】ISO8583报文解析

    ISO8583报文(简称8583包)又称8583报文,是一个国际标准的包格式,最多由128个字段域组成,每个域都有统一的规定,并有定长与变长之分. [报文格式] POS终端上送POS中心的消息报文结构 ...

  3. 【深入nodejs开发】一、将node项目结合nginx部署到Centos7服务器

    一.安装nginx服务器环境 1.使用ssh工具连接服务器 2.安装宝塔面板,方便服务器管理 yum install -y wget && wget -O install.sh htt ...

  4. 两个input之间有空隙,处理方法

    修改css,给前边一个input添加一个左浮动.   <input id="day" type="button" value="日" ...

  5. Spring配置文件里加载路径中的通配符

    ?代表匹配任意一个字符            *代表匹配0个或多个任意字符             **/匹配任意多个目录 classpath:app-Beans.xml 查找app-Beans.xm ...

  6. 转 MySQL: Starting MySQL….. ERROR! The server quit without updating PID file解决办法

    http://blog.sina.com.cn/s/blog_637e04c9010117ri.html 1 问题 [root@localhost mysql]# /etc/rc.d/init.d/m ...

  7. WdatePicker没有效果怎么办

    1:如果WdatePicker没有效果时间输入框 或报 invalid property:firstDayOfWeek 个错误. 2:网上解决方法有很多,但很多都不规范. 解决方法:重新下载(下载地址 ...

  8. Cetos 7 命令行登陆与图形界面登陆相互切换

    环境:vmware 虚拟机: 系统:Cetos 7 64位: 引言:有一台虚拟机,安装的时候选择的是最小化安装,是没有图形界面的,后来有需求,需要有个图形界面,所以就准备把这个升级下,下面是操作步骤: ...

  9. 为什么单个TCP连接很难占满带宽

    计算 TCP吞吐量的公式 TCP窗口大小(bits) / 延迟(秒) = 每秒吞吐量(bits) 比如说windows系统一般的窗口大小为64K, 中国到美国的网络延迟为150ms. 64KB = 6 ...

  10. 利用canvas对图片进行切割

    使用input标签选择一张图片, 然后利用canvas对图片进行切割, 可以设置切割的行数和列数 这是html代码 ... <input type="file" id=&qu ...