搭建自己的框架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); } } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端