在前一篇文章中,介绍了如何使用Unity来接管PIAB进行拦截操作,而Unity自身也提供了类似于ICallHandler的拦截处理程序——IInterceptionBehavior,今天这篇文章就是主要是关于如何使用IInterceptionBehavior和Unity自带拦截器的相关信息。

以下是本文所要介绍的内容:

1、创建自定义InterceptionBehavior

2、三种拦截器的优缺点

3、三种拦截器的使用方法

一、创建自定义InterceptionBehavior

IInterceptionBehavior和ICallHandler非常的类似,看下具体的定义代码:

public interface IInterceptionBehavior
{bool WillExecute { get; }IEnumerable<Type> GetRequiredInterfaces();IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext);
}

1、属性WillExecute ,指示拦截行为是否可被执行。

2、列表GetRequiredInterfaces,用于返回拦截所需的相关接口列表。

3、方法Invoke,具体的调用执行方法,可以在此方法处编写相关业务逻辑代码。

在了解了IInterceptionBehavior相关的代码后,我们就可以开始进行编写相关自定义拦截行为了,不过在此之前先要看下实验所需的一些相关接口和类:

接口IStudent:

public interface IStudent
{string Name { get; set; }int Age { get; set; }void ShowInfo();void VirtualShowInfo();
}

实现类Student1:

public class Student1 : IStudent
{public void ShowInfo(){Console.WriteLine("学生姓名:" + this.Name);Console.WriteLine("学生年龄:" + this.Age.ToString());}public virtual void VirtualShowInfo(){Console.WriteLine("虚拟方法调用");Console.WriteLine("学生姓名:" + this.Name);Console.WriteLine("学生年龄:" + this.Age.ToString());}private string _name = "顾磊";public string Name{get{return _name;}set{_name = value;}}private int _age = 22;public int Age{get{return _age;}set{_age = value;}}
}

其中VirtualShowInfo是为了介绍VirtualMethodInterceptor而用的,后面会介绍到。

现在开始编写具体的拦截行为,这边的拦截行为很简单,就是在调用具体的方法前输出一些字符,具体代码如下:

public class LogBehavior : IInterceptionBehavior
{private static readonly MethodInfo methodInfo =typeof(IStudent).GetMethod("ShowInfo");public IEnumerable<Type> GetRequiredInterfaces(){return new[] { typeof(IStudent) };}public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext){//检查参数是否存在if (input == null) throw new ArgumentNullException("input");if (getNext == null) throw new ArgumentNullException("getNext");if (input.MethodBase == methodInfo){Console.WriteLine("开始日志记录");Console.WriteLine("日志记录完成");Console.WriteLine("调用具体方法开始");return getNext()(input, getNext);}else{return input.CreateMethodReturn(null);}}public bool WillExecute{get { return true; }}
}

这个具体的拦截行为类中有几个需要注意:

1、由于GetRequiredInterfaces是返回拦截相关的接口,所以我这边仅返回IStudent既可。

2、将属性WillExecute置为true,表示可执行。

3、定义一个静态变量methodInfo用于记录接口IStudent下方法ShowInfo信息,由于在实际的拦截过程中Invoke会被执行多次,所以需要针对实际需要拦截的方法进行处理,只有调用到方法ShowInfo时才进行拦截,如果调用到的是方法ShowInfo则输出相应的字符,如果不是则调用input.CreateMethodReturn方法,返回一个无效的IMethodReturn 。

接下来看下如何通过Unity容器来调用这个拦截行为,具体代码如下:

public static void TestInterception()
{container.AddNewExtension<Interception>();container.RegisterType<IStudent, Student1>(//透明代理拦截//new Interceptor<TransparentProxyInterceptor>(),//接口拦截,与上面的透明拦截效果一样new Interceptor<InterfaceInterceptor>(),new InterceptionBehavior<LogBehavior>(),new InterceptionBehavior<LogBehavior2>());var studentInfo = container.Resolve<IStudent>();studentInfo.ShowInfo();
}

此处也有几点需要注意:

1、必须为容器增加一个新的扩展AddNewExtension<Interception>();

2、拦截行为必须有一个对应的拦截器,上面代码中分别使用了TransparentProxyInterceptor(透明代理拦截器)和InterfaceInterceptor(接口拦截器)

3、可以为一个拦截器添加多个拦截行为,这样做更多的事情。

配置代码文件如下:

<alias alias="IStudent" type="UnityStudyConsole.IDemo.IStudent, UnityStudyConsole" />
<alias alias="Student1" type="UnityStudyConsole.Demo.Student1, UnityStudyConsole" />
<alias alias="LogBehavior" type="UnityStudyConsole.InterceptionBehavior.LogBehavior, UnityStudyConsole" />
<alias alias="LogBehavior2" type="UnityStudyConsole.InterceptionBehavior.LogBehavior2, UnityStudyConsole" />
<container name="Forth"><!--为容器增加Interception扩展,如不增加下面interception配置会报错--><extension type="Interception"/><register type="IStudent" mapTo="Student1"><interceptor isDefaultForType="true" type="InterfaceInterceptor"/><interceptionBehavior type="LogBehavior"/><interceptionBehavior type="LogBehavior2"/></register>
</container>

其效果图如下:

二、三种拦截器的优缺点

Untiy内置了3种拦截器,下面说一下这3种拦截器的优缺点:

1、TransparentProxyInterceptor,透明代理拦截器(实例拦截器),使用.NET TransparentProxy/RealProxy技术来进行拦截

优点:可以拦截对象(虚拟的、非虚拟的以及接口)的所有方法

缺点:拦截的对象必须实现MarshalByRefObject或者实现一个接口,处理的速度过慢。

2、InterfaceInterceptor,接口拦截(实例拦截器),使用动态代码创建一个代理类来进行拦截。

优点:可以拦截所有实现了接口的对象,处理速度比TransparentProxyInterceptor快。

缺点:只能拦截实现了单一接口的方法。

3、VirtualMethodInterceptor,虚拟方法拦截器(类型拦截器),使用动态代码构建一个派生类来代替拦截原始类。

优点:处理速度比TransparentProxyInterceptor快。

缺点:只能拦截虚拟方法。

了解了3种拦截的优缺点后我们可以根据实际的需求来进行选择拦截器。

三、三种拦截器的使用方法

虽说是三种拦截器的使用方法,但其中2种(TransparentProxyInterceptor和InterfaceInterceptor)已经在上面的代码中介绍了,这般主要介绍VirtualMethodInterceptor的使用方法。

由于VirtualMethodInterceptor的特殊性,只能拦截虚拟方法,而在接口的定义过程中,接口中的方法是不能定义为virtual的,但是又要使用VirtualMethodInterceptor的时候需要做以下处理:

1、在接口的实现类中为指定方法增加virtual关键字,如上面的方法VirtualShowInfo

2、更改拦截行为中,拦截方法的获取,如:typeof(Student1).GetMethod("VirtualShowInfo"),直接从指定类中获取方法。

3、更改具体的注册代码,如下:

public static void TestVirtualMethodInterceptor()
{container.AddNewExtension<Interception>();container.RegisterType<Student1>(new Interceptor<VirtualMethodInterceptor>(),new InterceptionBehavior<LogBehavior3>(),new AdditionalInterface<IStudent>());var studentInfo = container.Resolve<Student1>();studentInfo.VirtualShowInfo();
}

可以看到上面的代码中直接是对具体的实现类添加拦截器和拦截行为,但是由于其本质还是依赖于IStudent接口,所以还需为其添加一个额外的接口注册new AdditionalInterface<IStudent>(),这样修改以后,运行效果和上面是一样的。

具体配置代码如下:

<container name="Fifth"><!--为容器增加Interception扩展,如不增加下面interception配置会报错--><extension type="Interception"/><register type="Student1"><interceptor isDefaultForType="true" type="VirtualMethodInterceptor"/><interceptionBehavior type="LogBehavior3"/><addInterface type="IStudent"/></register>
</container>

以上就是本文的所有内容了,谢谢阅读到此!

话说,各位看过的朋友如果觉得本文对您还有点用,或者觉得本文还有价值的话,麻烦将鼠标移到【推荐】上,帮我点击下,非常非常的感谢!

源代码下载:点我下载

微软企业库5.0 学习之路系列文章索引:

第一步、基本入门

第二步、使用VS2010+Data Access模块建立多数据库项目

第三步、为项目加上异常处理(采用自定义扩展方式记录到数据库中)

第四步、使用缓存提高网站的性能(EntLib Caching)

第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——上篇

第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——中篇

第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——下篇

第六步、使用Validation模块进行服务器端数据验证

第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—上篇

第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—下篇

第八步、使用Configuration Setting模块等多种方式分类管理企业库配置信息

第九步、使用PolicyInjection模块进行AOP—PART1——基本使用介绍

第九步、使用PolicyInjection模块进行AOP—PART2——自定义Matching Rule

第九步、使用PolicyInjection模块进行AOP—PART3——内置Call Handler介绍

第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录

第十步、使用Unity解耦你的系统—PART1——为什么要使用Unity?

第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(1)

第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(2)

第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(3)

第十步、使用Unity解耦你的系统—PART3——依赖注入

第十步、使用Unity解耦你的系统—PART4——Unity&PIAB

第十步、使用Unity解耦你的系统—PART5——使用Unity自身的拦截器

扩展学习:

扩展学习篇、库中的依赖关系注入(重构 Microsoft Enterprise Library)[转]

转载于:https://www.cnblogs.com/kyo-yo/archive/2010/12/27/Learning-EntLib-Tenth-Decoupling-Your-System-Using-The-Unity-PART5-Use-Unity-Interceptor.html

[EntLib]微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART5——使用Unity自身的拦截器...相关推荐

  1. (转)[EntLib]微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(1)...

    原文地址:http://www.cnblogs.com/kyo-yo/archive/2010/11/01/Learning-EntLib-Tenth-Decoupling-Your-System-U ...

  2. [EntLib]微软企业库5.0 学习之路——第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——上篇...

    本文是为后面的学习之路做铺垫,简单介绍下企业库中的Validation模块的一些相关知识,包括Validation模块的简介.用途.使用方法.默认提供的多种验证器的介绍等. 一.简介及用途 在实际的项 ...

  3. [EntLib]微软企业库5.0 学习之路——第七步、Cryptographer加密模块简单分析、自定义加密接口及使用—上篇...

    在完成了后,今天开始介绍企业库中的新模块:Cryptographer(加密模块),这个模块在日常的大多数项目的作用非常重要,例如:网站会员密码.身份证号.网站配置等,通过对信息进行加密可以保证项目数据 ...

  4. 微软企业库5.0 学习之路——UnityPIAB 通过配置实现AOP

    完全通过配置实现AOP的资料太少了,今天忙了好几个小时终于走通了,分享一下. 模拟业务是:登陆,记录登陆日志. // 业务接口 public interface IStudentManage{bool ...

  5. 微软企业库5.0学习笔记(三十三)数据访问模块

    前言 鉴于企业库5.0已经发布正式版,同时有广大读者的要求(臭屁一下,o(∩_∩)o...),后面文章的内容和代码将基于Enterprise Library5.0和Unity2.0来写,感谢大家的一贯 ...

  6. 微软企业库4.1学习笔记(三十六)日志模块 简介

    日志模块 企业库的日志模块简单的实现了日志功能的常用功能.开发者可以利用模块在下面的位置记录信息: 事件日志 电子邮件 数据库 消息队列 文本文件 WMI的事件查看器 自定义的位置 模块为记录在任何位 ...

  7. 微软企业库5.0学习笔记(四)配置企业库

    http://blog.csdn.net/sfbirp/archive/2010/05/18/5603567.aspx 转载于:https://www.cnblogs.com/Rising/archi ...

  8. 微软企业库4.1学习笔记(三)企业库迁移和并行使用,以及企业库的扩展

    一.迁移和并行使用 通常来说,企业库是建立在.NET 2.0 的基础上,使用后续版本的企业库也不需要改变任何代码.不需要将引用更新到新的程序集,也不需要在配置文件中指明程序集的正确版本. 这个版本4. ...

  9. 微软企业库4.1学习笔记(八)创建对象 续集2

    3.3通过配置指定和Unity的整合 另外一种方法是在配置源中指定配置的需要,你可以指定下面的一条或者多条: 你可以在Unity配置中指定想要的BlockExtensions 你可以在Unity配置中 ...

最新文章

  1. Redis——学习之路四(初识主从配置)
  2. 5G NGC — AUSF 鉴权服务功能
  3. Weights Assignment For Tree Edges 树,拓扑序(1500)
  4. WIF(Windows Identity Foundation) 被动联合身份验证过程详解
  5. PIC32单片机harmony开发环境 - i2c例程和代码分析
  6. OCA第2部分中的Java难题
  7. 用python计算准确率_Pytorch 计算误判率,计算准确率,计算召回率的例子
  8. MySQL 如何查找并删除重复行
  9. Try Catch C++ 异常捕获
  10. Mutex和内存可见性
  11. IOS NSLayoutConstraint 页面布局(通过代码添加约束)
  12. Flash 3D 基础
  13. 网页设计课设【登录注册系统及增删改查】
  14. 印度黑客号称世界第一,结果第二天被中国黑客干掉了
  15. 苹果 开发者账号如下
  16. 分享知识-快乐自己:oracle12c创建用户提示ORA-65096:公用用户名或角色无效
  17. 关于html video 在chrome浏览器下无法快进问题解决
  18. 虚幻浏览器插件 加载透明网页
  19. 记一次Windows勒索病毒应急响应实战
  20. 今天主要学习vue的一些原理,尤其是vueComponent与Vue的关系,个人觉得值得反复回味,很巧妙

热门文章

  1. Altium Designer应用技巧12: 下载TI官方库
  2. 微服务springcloud+Vue的在线汽车用品销售商城平台
  3. Photoshop Elements 2022 Mac(简化版ps图像编辑软件)内附完整教程
  4. Python C# 通信2种路子
  5. 3D照片墙源码(直接使用)
  6. 已知:关系模式R(U,F),U=ABCD,F={A→C,C→A,B→AC,D→AC},将模式R无损失连接并保持函数依赖,分解为3NF
  7. 【可穿戴算法开发】-基于PPG信号的血氧与血压检测模型
  8. 最长单调递增子序列 动态规划 (java)
  9. 【秋招机试真题】网易笔试0919
  10. COSMOS认证和LOGO只限用于化妆品及选择有机护肤品主要看哪几方面 认证咨询