untiy 从nuget上下载
项目为简单三层架构。 接口--业务逻辑层--数据访问层--数据实体层。
接口定义 业务层和数据访问层 接口。
需求实现使用Unity 能够集成异常管理
一、介绍一下业务逻辑
客户端 调用bll.GetList();获取后台数据。bll中调用的是dal.GetList();
我们希望在 调用GetList 系统能够自动处理异常。不要再在每个方法中都去写
try{}catch{}。这样很麻烦业务逻辑也显得臃肿。
二、定义异常标签,异常处理handler
要想解决以上问题,可以用Unity的拦截机制这样做,定义异常特性或者叫属性
namespace Common { public class ExceptionExpandAttribute : HandlerAttribute { public int ID { get; set; } // 摘要: // Derived classes implement this method. When called, it creates a new call // handler as specified in the attribute configuration. // // 参数: // container: // The Microsoft.Practices.Unity.IUnityContainer to use when creating handlers, // if necessary. // // 返回结果: // A new call handler object. public override ICallHandler CreateHandler(IUnityContainer container) { var handler = container.Resolve<ExceptionHandler>(); handler.Order = this.Order; handler.ID = ID; return handler; } } }
建立异常处理handler
public class ExceptionHandler:ICallHandler { public int Order { get; set; } public int ID { get; set; } public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { if (ID == 100) throw new Exception("AOP异常处理出现异常:Dal出现异常"); var methodReturn = getNext().Invoke(input, getNext); if (methodReturn.Exception != null) throw new Exception("AOP异常处理出现异常", methodReturn.Exception); return methodReturn; } }
实现ICallHandler的 Invoke 方法,input 能够截获到调用方法传入的参数,getNext().Invoke(input, getNext); 能够得到返回值。我们在
getNext().Invoke(input, getNext);此方法执行后可以截获异常,并进行封装,这里简写。
给要进行异常处理的方法加上标签
public interface IBll { [ExceptionExpand(Order=1,ID=10)] List<QueryModel> GetList(); } public interface IDal { [ExceptionExpand(Order = 1, ID = 100)] List<QueryModel> GetList(); }
然后,前台在配置文件中配置各个对象
三、配置文件配置
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" /> <alias alias="IBll" type="InterfaceDefined.IBll,InterfaceDefined" /> <alias alias="IDal" type="InterfaceDefined.IDal,InterfaceDefined" /> <container> <extension type="Interception" /> <register type="IBll" mapTo="BusinessEntiy.Bll,BusinessEntiy" > <constructor> <param name="Name" value="nihao" /> </constructor> <interceptor type="TransparentProxyInterceptor" /> <policyInjection /> </register> <register type="IDal" mapTo="DataAccess.Dal,DataAccess" > <interceptor type="TransparentProxyInterceptor" /> <policyInjection /> </register> </container> </unity>
很简单指定注册类,指定类初始化参数,interceptor类型使用TransparentProxyInterceptor
测试:
其他日志,缓存大同小异,写的简单,好理解。