在日常程序开发、维护、运行过程中,经常出现各种异常,需要多处异常处理程序来捕捉异常,同时进行异常记录,有没有更方便的一种方式呢?最近在看Aop的相关实现.应用AOP来处理异常,记录相关信息,同时返回相应的错误值继续程序运行.下面我们来看看异常的相关处理信息.
(一) 首先我们先看一下异常的相关疑点..
1.异常可以被自动传递,直到处理程序捕捉到为止.这样.
2.UI层为了良好的用户体验,不能抛出新的异常,替代以更友好的提示信息.
3.其它地方捕捉异常(UI外)通常处理掉/继续抛出/包装后抛出
4.如果抛出自定义异常,最好将此异常信息描述的越清晰越好,放边定位,修改程序.
5.开发试运营阶段,经常出现各种异常问题,或者想掌握相关调用信息,同时处理异常,那么Aop是其中一个解决办法.
(二)Aop处理异常相关应用疑点.
1.能否捕捉到方法掉用中捕捉到所有异常.
2.捕捉后记录详细的异常信息,包括异常所在的类、方法、传递InArgs、返回的OutArgs.
3.记录异常后能否返回相应的返回值.
4.Aop异常处理所带来的性能问题.
(三)Aop异常处理相关实现.
1.先定义一个AspectAttribute,此AspectAttribute继承类Attribute,实现接口IContextAttribute,IContextProperty.同时标注 [Serializable,AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)] 保证此类可以序列化,同时可以应用到类和方法上面.有人会说了,既然应用到类上了,那里面的方法不是自动就能调用了,为什么还要定义到方法里面呢,就是可以覆盖类里面的定义
[Serializable,AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)] public virtual bool IsNewContextOK(Context context) public virtual void Freeze(Context newContext) if(ctorCallMsg == null) if(!ctorCallMsg.ActivationType.IsContextful) object obj = context.GetProperty(Name); return false; public abstract AspectProperty GetContextProperty(string aopName); } |
2. 自定义一个上下文属性,以便插入到Aop上下文里面实现接口IContextProperty,IContributeServerContextSink
public virtual IMessageSink GetServerContextSink(IMessageSink nextSink)
{
return null;
} 这里没有任何实现,主要由子类来实现.
3. 自定义一个上下文链AspectSink,来处理异常程序.实现接口IMessageSink.主要的就是这个SyncProcessMessage方法进行Aop 插入处理.
{ public IMessage SyncProcessMessage(IMessage msg) if(!(msg is IConstructionCallMessage)) AfterAopHandle afterHandle = this.FindAfterHandle(AopPropertyName); return SyncWrapProcessMessage(msg,returnMsg); |
4.这里就是我们异常的自定义ExceptionAttribute,这里主要是关注一下构造函数,看见了没?有个参数object returnValue,这就是代表出现异常时你可以自定义你想要的返回信息.
private object returnValue; public ExceptionAttribute(object returnValue) |
5.异常处理链 ExceptionSink.这里实现异常处理,和异常记录功能.主要是对IMethodReturnMessage进行包装,达到处理目的.
public override IMessage SyncWrapProcessMessage(IMessage msg, IMethodReturnMessage returnMsg) { MethodReturnMessageWrapper wrapMsg = new MethodReturnMessageWrapper(returnMsg); if(wrapMsg.Exception != null) { wrapMsg.Exception = null; object[] logAttribute = returnMsg.MethodBase.GetCustomAttributes(typeof(ExceptionAttribute),true); if(logAttribute.Length == 0) logAttribute = returnMsg.MethodBase.DeclaringType.GetCustomAttributes(typeof(ExceptionAttribute),true); wrapMsg.ReturnValue = (logAttribute[0] as ExceptionAttribute).ReturnValue; } return wrapMsg; } |
(四)Aop异常管理调用测试
1.需要异常管理的类,此处为CalculateTest,它继承ContextBoundObject而来,上有[ExceptionAttribute]约束,代码接受异常管理,默认异常处理后返回null,下面方法public string CalculateLog(int a)则加标签[ExceptionAttribute("I Love You to")]表示,此处覆盖类定义,异常处理后返回的是"I Love You".[ExceptionAttribute(123456789)]异常则返回123456789
[ExceptionAttribute] [ExceptionAttribute(123456789)] public DataSet TestForDataSet(string tableName) |
2.测试类
static void Main(string[] args) int result1 = cls.CalculateLog(1,2,3); string result2 = cls.CalculateLog(1); DataSet ds = cls.TestForDataSet("THIS IS A NULL TABLE"); } |
3.最终结果如下图,成功记录了方法调用之前的信息,异常出现的信息,异常处理后返回的值信息,处理之后的其它信息.
以上这些就是基础的实现了,还等什么呢 把代码DOWN下去自己编译运行一下, 在类ClassTest加个断点一步一步的调试一下,什么都明白了.以后工作中的异常是不是就可以归Aop处理了呢?
欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛
https://bbs.txwb.com
关注天下网吧微信/下载天下网吧APP/天下网吧小程序,一起来超精彩
|
本文来源:vczx 作者:佚名