异常捕捉、处理是每个项目中必不可少的一部分,利用反射和XML配置技术实现一个通用的、灵活的、可配置的、高度可自扩展的异常处理框架对项目的整体健壮性以及异常处理效率都是非常重要的。通用异常处理框架中需要提供配置信息的支持以及统一的异常处理类和异常日志记录类管理,并允许用户以插件形式扩展自定义的异常处理或日志记录方式。
由于异常处理在项目中的普遍性,我们会很自然的想到是否可以对异常处理模块进行提取为公用模块,加强项目间的复用,提高项目的开发进度。并且在异常处理中,因为没有良好的异常处理系统可能造成一些问题:
为了最大程度实现异常处理框架的通用性、可扩展性以及可配置性,采用配置文件结合动态加载插件的方式:框架提供接口,由不同项目根据自己的需要实现接口,完成对异常的处理,以及异常日志的记录;而框架再根据配置信息决定异常处理在不同的情况下的处理策略,并通过调用用户实现的接口来完成异常处理过程。
整个异常处理过程对项目调用高度封装,项目中不论任何地方,只需调用一个唯一的接口,框架就会根据配置信息执行需要的异常处理。
框架主要由ExManagement.Config、ExManagement.Interface、ExManagement.MessageHandler以及ExManagement构成。如图:三-1
该包主要由两部分组成:实现System.Configuration.IConfigurationSectionHandler接口的ExSectionHandler类和配置信息实体类ExManagerConfig。如图三-2。
ExManagerConfig类中又定义了3个嵌入类:ExHandlerConfig、LogHandlerConfig、LogHandlerConfigCollection以及三个枚举ExAlertType、ErrorCodeSource、ExReturnMode。ExManagerConfig,ExHandlerConfig、LogHandlerConfig分别对应配置文件中的 、 、 节点。ExManagerConfig是一个集合类,从System.Collections.CollectionBase继承,包含若干个ExHandlerConfig对象,并通过索引器访问包含的ExHandlerConfig对象,支持以int和string两种方式索引。ExHandlerConfig中除了包含对应节的属性外,还包含一个LogHandlerConfigCollection对象,是LogHandler类的集合类。
图三-2
ExSectionHandler类从配置文件中按照固定的格式获取到相应的配置信息,并将信息填充到ExManagerConfig。
配置文件
首先需要在Web.Config或者App.Config中添加这行
这句是指定用ExManagement.Config.ExSectionHandler类来处理ExManager配置节点
ExManagement.Interface包
包含了IExLogHandler和I Message两个接口以及ExHandlerBase基类,可以通过实现这些接口来对框架进行扩展。如图三-3:
图三-3
以下是ExHandlerBase基类中加载所有异常日志对象的方法:
通过遍历配置文件中该节包含的所有子节点,并将配置中指定的LogHandler类反射实例化,将对象存入队列中。
该包包含两个IMessage接口的实现,分别完成对异常信息在WinUI和WebUI中的弹出提示功能。WinFormMessage和WebMessage分别引用了System.Web.Dll和System. Windows.Forms.Dll。如图三-4。
图三-4
包含了ExManager类和ErrorInfo类,是框架中核心的业务流程控制模块。如图三-5
图三-5
ErrorInfo类:根据ErrorId查询对应的ErrorString。在这个类里,会根据在配置文件中节的值去指定的数据源(XML文件或者数据库)查询。
ExManager类,该类是一个单例类,会在第一次实例化时获取配置信息实体对象,并按照配置文件把所有指定的异常处理类实例化后并存入一个哈希表中。以后实例化该类都会重复使用之前实例化的该对象,避免反射造成的性能影响。通过调用该类的ProcessException()方法将捕捉到的异常对象,错误编号,用来处理异常的异常处理器名(建议为该层的名称)传递给框架,并按照参数从哈希表中取出对应的异常处理对象,调用接口对异常进行处理。
ExManagement.Handler包
只包含一个默认的异常处理器类:DefaultExHandler,它从ExHandlerBase基类继承。下面是该类里最重要的ProcessExeception方法。
在这个默认的异常处理类的ProcessExeception方法中首先调用该类中处理日志记录的方法,再根据配置中的ExReturnMode决定返回处理的结果方式,对异常进行处理。特别是当设置为返回方式为Exception,即抛出异常对象时是先判断该异常是否是最初发生的异常,还是已经处理包装过的异常,避免重复处理异常(不管异常是来自本层或者其他层)。
该包只有一个默认的DefaultLogHandler类,实现了ILogHandler接口,它负责把异常信息记录到数据库中。
BusinessLogicLayer
配置意义为:根据ErrorId到数据库ErrorInfo库中获取ErrorString,定义了一个ExHandler,名为BusinessLogicLayer的框架默认的异常处理类,异常返回方式为抛出异常对象,因为不是UI层,所以AlerType为None,该异常处理类用一个默认的LogHandler把异常日志记录到数据库ExceptionLog。
BusinessFacadeLayer
该层配置除ExHandler的Name不同外,与BusinessFacadeLayer的配置基本一致。
WebUILayer
该层的异常处理器的ReturnMode方式为ExceptionString(即Exception.Message),弹出提示方式为WebUI。
WinUILayer
该层和WebUILayer的配置除AlertType为WinUI方式外,基本一致。
以上配置为开发调试方式时,若是在发布到测试或正式环境,只需要把WinUILayer和WebUILayer中的ReturnMode属性更改为ErrorString方式,即可让用户看到的是友好的错误信息。
补充:WinUI项目的异常日志记录器可以再增添一个本地异常Log文件方式,当发生异常时,可以根据用户提供的Log文件进行分析。
在写好配置文件之后,项目中引用ExManagement包。调用方法如下,项目中任何地方调用处理方式完全一致
四、效果评价
可配置性。通过该异常处理框架可以方便的对异常处理进行需要的配置。可配置的内容:
可以配置多个异常日志记录以不同的方式记录在不同的位置;
异常处理方式可以有多种:抛出包装后异常对象、 返回详细的异常信息(调试用)、返回错误提示信息(发布后给用户看)以及错误编号;
灵活性。建立在可配置性的基础上,可以组合出多种异常处理方案,以满足不同项目的特殊需要。
开放的可扩展性。用户可以自行实现框架提供的接口,自行扩展异常处理以及异常日志记录的类,以插件形式供框架调用,以实现最大可能的灵活性。
性能。因为使用了不少反射技术,在性能上有一定损耗,但使用了单例模式来弥补,只在项目第一出现异常的时候反射加载对象,以后再次调用时则直接使用该对象,对效率基本没有任何损耗了。
而多数情况下,以框架提供的默认解决方案已经能够满足普通项目的需要,提供一个功能比较完整的,健壮的异常处理机制:
1) 方便和简化了开发人员及时定位和发现异常原因;
2) 对系统运行状况提供了强有力的数据支持,并使错误信息统一的方式管理,可以改善用户体验;
3) 当项目在用户使用中发现运行错误时,可以记下系统反馈的异常记录编号后于项目开发人员联系,而开发人员可以根据记录编号得到异常发生的详细信息进行分析。有助于缩短项目异常反馈时间。
该异常处理框架基本适合所有.Net项目,因为可以灵活的配置以适应不同项目的具体需要。
在一个项目推广中,只需要有一个人比较深入的了解该异常处理框架的原理以及如何进行配置和自定义扩展开发,掌握时间大概只需要半天到一天时间。而项目中其他人员无须知道该框架的运行机制,他们只需要在每个捕捉异常的地方用同样的、唯一的方法调用框架即可。
因为该框架对于项目而言是高度聚合,低耦合的,对于项目而言不需要知道异常究竟会被如何处理,减少对项目的依赖。因此对于现有异常处理系统存在不足以及新项目是应该大力推荐使用该框架进行异常处理的,并且对现有项目的改造工作不大;当然也可以选择对项目已有部分不改动,新开发部分进行使用该框架进行异常处理也是完全可以的。
异常处理框架本身没有做任何自身的异常情况处理,所以在采用框架的时候需要先按照预想的配置在模拟环境中进行调试,确认能够正常运行之后再加入到正式项目中去,避免在正式环境中出现框架本身异常无法判断的情况。
当然因为异常处理的可能方案比较多,该框架的第一个版本可能会有遗漏的可能,但因为框架本身的良好扩展性,多数的特殊情况应该可以用户自行扩展解决。若有无法解决的可以和我联系,对框架本身代码做调整,以求完善该框架。
另外,该异常处理框架若与最近讨论比较热门的AOP(Aspect Oriented Programming面向方面编程)思想结合可以最大程度使系统的业务代码和系统异常处理代码完全分离,并提供更为准确的异常信息。因AOP技术目前在发展阶段,并需要完全的纯OOP项目中实施,暂不对此展开讨论。
0 0 标签: 异常处理
热门源码