搭建自己的框架WedeNet(三)
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(三)的更多相关文章
- 搭建自己的框架WedeNet(五)
WedeNet2018.WedeWcfServices-WCF服务层:结构如下: 就是定义了服务契约接口和服务类,以OrderServices为例,如下: using System; using Sy ...
- 搭建自己的框架WedeNet(四)
WedeNet2018.Web-UI层:结构如下: 首先,在Controller中定义BaseController,以便加入统一处理逻辑,如下: using log4net; using System ...
- 搭建自己的框架WedeNet(一)
框架用到的技术: EF.UnitOfWork+Repository.Ninject.log4net.WCF.MVC.T4.windows服务.AOP前端技术:Bootstrap.layer.jQuer ...
- 搭建自己的框架WedeNet(二)
WedeNet2018.Infrastructure-基础设施层:结构如下: Tools结构如下: 考虑到系统可能会有多个数据上下文(暂时以两个为例),所以根据需要定义两个T4模板用来生成对应的ent ...
- 如何搭建MVC + EF 框架
1.搭建MVC框架 1.1 VS2010:需要安装WPI 安装 ASP.NET MVC 4 和Visual Studio 2010 系统必备组件 如果上述链接无法打开,请访问:http://www.a ...
- Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED
Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED Xvfb+YSlow+ShowSlow搭建前端性能测试框架 作者:黑三 | 时间:2010-07-07 ...
- Windows环境搭建Web自动化测试框架Watir
Windows环境搭建Web自动化测试框架Watir 一.前言 Web自动化测试一直是一个比较迫切的问题,对于现在web开发的敏捷开发,却没有相对应的敏捷测试,故开此主题,一边研究,一边将We ...
- 搭建App主流框架_纯代码搭建(OC)
转载自:http://my.oschina.net/hejunbinlan/blog/529778?fromerr=EmSuX7PR 搭建主流框架界面 源码地址在文章末尾 达成效果 效果图 注:本文部 ...
- 【微服务】使用spring cloud搭建微服务框架,整理学习资料
写在前面 使用spring cloud搭建微服务框架,是我最近最主要的工作之一,一开始我使用bubbo加zookeeper制作了一个基于dubbo的微服务框架,然后被架构师否了,架构师曰:此物过时.随 ...
随机推荐
- sql 查询存在一个表而不在另一个表中的数据
方法一(效率底) select A.* from 办卡 A where A.namedh not in (select namedh from 银行) 方法二(效率中) select A.* from ...
- Process.Net
ProcessSharp的构造函数,对应的测试是 https://github.com/lolp1/Process.NET/blob/master/test/Process.NET.Test/Core ...
- PHP中的src32
crc32() 函数计算一个字符串的 crc32 多项式. 该函数可用于验证数据的完整性. 语法 crc32(str 参数 描述 string 必需.规定要计算的字符串. 说明 生成 string 参 ...
- 性能优化 | JVM与性能优化知识点综合整理
JVM JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器.它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序. java编译 ...
- 数据分析 - Excel 函数, 技巧, 分析工具
数据分析工具使用场景 函数 分类 文本清洗函数 FIND - 查找 find 函数查询指定位置的某字符的的位置 快捷键 : 选中后双击右下角的 + 可以快速生成当前一列结果 FIND("查询 ...
- vlc命令行: 转码 流化 推流
vlc命令行: 转码 流化 推流 写在命令行之前的话: VLC不仅仅可以通过界面进行播放,转码,流化,也可以通过命令行进行播放,转码和流化.还可以利用里面的SDK进行二次开发. vlc命令行使用方法: ...
- [GPU] Install H2O.ai
一.前言 主页:https://www.h2o.ai/products/h2o4gpu/ GPU版本安装:h2oai/h2o4gpu 采用GPU,能否成为超越下面链接中实验的存在? [ML] LIBS ...
- 在Java中使用元组类型的利器
Java本身并没有内置元组这一项特性,要使用元组必须自行实现,所幸现在这些编程语言都支持泛型, 实现非内置元组也变的异常简单, 但是毕竟是非语言内置的语法元素,使用起来肯定不如原生元组来的便捷. 下面 ...
- 启动nfs清除端口占用过程
centos7起nfs服务. 按教程执行: vim /etc/exportsyum install -y nfs-utils systemctl enable rpcbind.service syst ...
- 爬虫——简单处理js中嵌入的json数据
看了群里一个人提问道https://www.amazon.com/,商品分类那里无法用xpath拿得到列表.遂对其研究. 通过抓包工具可以得知,原始数据存在于js代码中,我的方式是手动解析js,从里面 ...