我心中的核心组件(可插拔的AOP)~第四回 异常拦截器
之前说过有关拦截器的文章,第二回 缓存拦截器,事实上,在那讲里说的最多是AOP和缓存组件,对于拦截的概念并没有详细的说明,这一讲,不说AOP,主要说一下拦截器,拦截器Interception,主要是在方法执行前或者执行后,动态添加一些行为,而这个行为主要包含缓存,日志,异常处理及你可以想到的所有的一切,呵呵。
这一讲是异常拦截器,它的主要意义在于,当你的一个方法被执行时,你可以通过配置文件去管理这个方法执行前与执行后是否附加统一异常处理行为。
拦截器组件我们还是用Unity.InterceptionExtension,它依附于Unity,当你没有安装Unity时,Unity.InterceptionExtension在安装时会自己帮你添加上,这是正确的,呵呵。
对于我们所开发的拦截器,必须要实现IInterceptionBehavior这个接口才可以,这是接口的内容
// 摘要: // Interception behaviors implement this interface and are called for each invocation // of the pipelines that they're included in. public interface IInterceptionBehavior { // 摘要: // Returns a flag indicating if this behavior will actually do anything when // invoked. // // 备注: // This is used to optimize interception. If the behaviors won't actually do // anything (for example, PIAB where no policies match) then the interception // mechanism can be skipped completely. bool WillExecute { get; } // 摘要: // Returns the interfaces required by the behavior for the objects it intercepts. // // 返回结果: // The required interfaces. IEnumerable<Type> GetRequiredInterfaces(); // // 摘要: // Implement this method to execute your behavior processing. // // 参数: // input: // Inputs to the current call to the target. // // getNext: // Delegate to execute to get the next delegate in the behavior chain. // // 返回结果: // Return value from the target. IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext); }
其中Invoke方法就是拦截方法之前要执行的方法,当进行目标方法时,首先会检测是否在此方法的信息,如果有,就进行拦截行为,本例为异常拦截行为。
异常拦截器代码:
/// <summary> /// 表示用于异常日志记录的拦截行为。 /// </summary> public class ExceptionLoggingBehavior : IInterceptionBehavior { #region IInterceptionBehavior Members /// <summary> /// 获取当前行为需要拦截的对象类型接口。 /// </summary> /// <returns>所有需要拦截的对象类型接口。</returns> public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; } /// <summary> /// 通过实现此方法来拦截调用并执行所需的拦截行为。 /// </summary> /// <param name="input">调用拦截目标时的输入信息。</param> /// <param name="getNext">通过行为链来获取下一个拦截行为的委托。</param> /// <returns>从拦截目标获得的返回信息。</returns> public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) { var methodReturn = getNext().Invoke(input, getNext); if (methodReturn.Exception != null) { Utils.Log(methodReturn.Exception); } return methodReturn; } /// <summary> /// 获取一个<see cref="Boolean"/>值,该值表示当前拦截行为被调用时,是否真的需要执行 /// 某些操作。 /// </summary> public bool WillExecute { get { return true; } } #endregion }
而要想使拦截器起作用,我们可以在配置文件中进行配置,下面是缓存拦截与异常拦截的配置代码,它们隶属于Unity节点
<!--BEGIN: Unity--> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" /> <container> <extension type="Interception" /> <register type="Infrastructure.Caching.ICacheProvider, DDD_AOP_WCF.Infrastructure" mapTo="Infrastructure.Caching.EntLibCacheProvider, DDD_AOP_WCF.Infrastructure" /> <!--对数据上下文的注入--> <register type="DDD_AOP_WCF.Domain.Repository.IProductRepository, DDD_AOP_WCF.Domain" mapTo="DDD_AOP_WCF.Infrastructure.Repository.ProductRepository, DDD_AOP_WCF.Infrastructure" /> <!--对WCF的访问进行的注入与缓存和异常的拦截--> <register type="DDD_AOP_WCF.ServiceContracts.IProductService, DDD_AOP_WCF.ServiceContracts" mapTo="DDD_AOP_WCF.Service.Implements.ProductServiceImpl, DDD_AOP_WCF.Service"> <!-- <interceptor type="VirtualMethodInterceptor" />--> <interceptor type="InterfaceInterceptor" /> <interceptionBehavior type="Infrastructure.InterceptionBehaviors.CachingBehavior, DDD_AOP_WCF.Infrastructure" /> <interceptionBehavior type="Infrastructure.InterceptionBehaviors.ExceptionLoggingBehavior, DDD_AOP_WCF.Infrastructure" /> </register> </container> </unity> <!--END: Unity-->
怎么样,大家是否对拦截器有一个很清楚的了解和认识了呢,呵呵!