首先,我们先要制作一个自定义Attribute,让他可以具有上下文读取功能,所以我们这个Attribute类要同时继承Attribute和IContextAttribute。

接口IContextAttribute中有两个方法需要实现

1、bool   IsContextOK(Context ctx, IConstructionCallMessage msg);

2、void  GetPropertiesForNewContext(IConstructionCallMessage msg);

简单解释一下这两个方法:

1、IsContextOK方法是让我们检查当前上下文(current  context)是否有问题,如果没有问题返回true,有问题的话返回false,然后该类会去调用GetPropertiesForNewContext

2、GetPropertiesForNewContext 是 系统会自动new一个context ,然后让我们去做些新环境应该做的事。

  1. /// <summary>
  2. /// Some class if you want to intercept,you must mark this attribute.
  3. /// </summary>
  4. public class InterceptAttribute : Attribute, IContextAttribute
  5. {
  6. public InterceptAttribute()
  7. {
  8. Console.WriteLine(" Call 'InterceptAttribute' - 'Constructor'  ");
  9. }
  10. public void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
  11. {
  12. ctorMsg.ContextProperties.Add(new InterceptProperty());
  13. }
  14. public bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
  15. {
  16. InterceptProperty interceptObject = ctx.GetProperty("Intercept") as InterceptProperty;
  17. return interceptObject != null;
  18. }
  19. }

ok,这是这个类的实现,要解释几点:

1、InterceptAttribute这个类继承的是Attribute,用于[Attribute]标记用的。

2、InterceptAttribute这个类继承IContextAttribute,用于给标记上的类获得上下文权限,然后要实现该接口的两个方法。

3、IsContextOK方法是去判断当前是否有“Intercept”这个属性,因为我们只需要这个属性,所以只要检查这个属性当前上下文有没有即可,如果有返回true,没有的话会调用GetPropertiesForNewContext函数。

(我们这里只做拦截器功能,所以只添加Intercept自定义属性,当然如果有需要可以添加多个属性,然后在这个函数中进行相应检查)

4、如果调用GetPropertiesForNewContext函数,他会让我们进行新上下文环境的自定义,我在这做了一个操作:在当前的上下文中添加一个属性,这个属性就是Intercept。

5、下一章我会实现InterceptProperty这个类,其实这个类就是一个上下文属性。

好了,接着上一篇文章,我们要实现一个InterceptProperty类。

先讲一下,这个类我们要继承两个接口IContextProperty和IContributeObjectSink

IContextProperty:这个接口是说明该类是一个上下文属性,他其中有两个方法IsNewContextOK和Freeze

1、Freeze()该方法用来定位被创建的Context的最后位置,一般不用写入什么逻辑。

2、IsNewContextOK()这个方法让我们检验:我们对当前新Context是否满意。满意返回true,不满意false则会异常,我们再进行处理。

IContributeObjectSink: 这个接口是是一个消息池,只有继承这个接口我们才能接收Object消息。

当然也有IContributeEnvoySink,IContributeClientContextSink,IContributeServerContextSink,这些消息池,能接收不同形式的消息,在这里不过多解释。

1、IContributeObjectSink 里面的 GetObjectSink()方法需要我们去实现,主要作用是得到一个消息池的对象。

好,话不多说,直接贴代码:

  1. //IContributeObjectSink,IContributeEnvoySink,IContributeClientContextSink,IContributeServerContextSink
  2. public class InterceptProperty:IContextProperty,IContributeObjectSink
  3. {
  4. public InterceptProperty()
  5. {
  6. Console.WriteLine(" Call 'InterceptProperty' - 'Constructor'  ");
  7. }
  8. public string Name {
  9. get
  10. {
  11. return "Intercept";
  12. }
  13. }
  14. public void Freeze(Context newContext)
  15. {
  16. }
  17. public bool IsNewContextOK(Context newCtx)
  18. {
  19. var result = newCtx.GetProperty("Intercept");
  20. return result!=null;
  21. //return false;
  22. }
  23. public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
  24. {
  25. InterceptSink interceptSink = new InterceptSink(nextSink);
  26. return interceptSink;
  27. }
  28. }
 

简单解释一下,IsNewContextOK() 函数中,我主要是在当前新的上下文中获得我想要的Intercept属性,正常情况下,系统会构造出InterceptProperty对象,GetProperty()函数就是get出Name属性是否匹配,如果匹配则return true,否则异常。
另外的GetObjectSink方法则是得到一个InterceptSink的对象,下一节我会实现InterceptSink类。

之前为InterceptAttribute的上下文环境添加了“Intercept”属性(InterceptProperty),正因为InterceptProperty继承了IContributeObjectSink,所以我们要实现GetObjectSink(),继而我们要创建一个继承ImessageSink的类来作为返回值。

这样就引发出了InterceptSink类的实现:

  1. public class InterceptSink : IMessageSink
  2. {
  3. private IMessageSink nextSink = null;
  4. public IMessageSink NextSink
  5. {
  6. get { return nextSink; }
  7. }
  8. public InterceptSink(IMessageSink nextSink)
  9. {
  10. Console.WriteLine(" Call 'InterceptSink' - 'Constructor'  ");
  11. this.nextSink = nextSink;
  12. }
  13. public IMessage SyncProcessMessage(IMessage msg)
  14. {
  15. Console.WriteLine("method_name: " + msg.Properties["__MethodName"].ToString());
  16. IMessage returnMsg = nextSink.SyncProcessMessage(msg);
  17. return returnMsg;
  18. }
  19. public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
  20. {
  21. return null;
  22. }
  23. }

核心方法是:SyncProcessMessage(Imessage msg)

传入参数msg中,我们可以找到调用对象方法的相应数据。

ok,我们拦截器基本构造完成,接下来我来告诉大家如何去使用。

注意一个问题,object拦截器我们要拦截什么,那么我们就要在需要拦截的类上面做手脚了。

首先,创建我们需要被拦截的类。

然后,我们再对类进行相应的包装:

1、该类要标记InterceptAttribute属性

2、该类要继承ContextBoundObject,只有继承ContextBoundObject的类,vs才能知道该类需要访问Context,这样标记的InterceptAttribute才有效。

  1. /// <summary>
  2. /// If you want to add the interceptpool on this class , the class need to do:
  3. /// 1、inherited form ContextBoundObject.
  4. /// 2、mark the InterceptAttribute.
  5. /// </summary>
  6. [Intercept]
  7. public class SimonDemo:ContextBoundObject
  8. {
  9. public SimonDemo()
  10. {
  11. Console.WriteLine(" Call 'SimonDemo' - 'Constructor'  ");
  12. }
  13. public void Operate1()
  14. {
  15. Console.WriteLine("Call 'SimonDemo' - 'Operate1' ");
  16. }
  17. }

然后,我们在Main函数中创建一个该类的对象,并进行调用方法。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. Console.WriteLine("Call Main ..");
  6. SimonDemo simon = new SimonDemo();
  7. simon.Operate1();
  8. Console.WriteLine("exit Main ..");
  9. Console.Read();
  10. }
  11. }

这样,通过调试,我们就可以看出拦截器都拦截出了什么

接下来是运行结果:

这样可以看出我的程序拦截,并输出了调用函数的名字。

(转)C#制作一个消息拦截器的更多相关文章

  1. C#制作一个消息拦截器(intercept)1

    首先,我们先要制作一个自己定义Attribute,让他能够具有上下文读取功能,所以我们这个Attribute类要同一时候继承Attribute和IContextAttribute. 接口IContex ...

  2. C# 通过Attribute制作的一个消息拦截器

    首先,我们先要制作一个自己定义Attribute,让他能够具有上下文读取功能,所以我们这个Attribute类要同一时候继承Attribute和IContextAttribute. 接口IContex ...

  3. 开发openfire 消息拦截器插件PacketInterceptor

    开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承PacketInterceptor包拦截类,然后在initializelPlugin()方法中注册拦截器,就可以实现inter ...

  4. 吴裕雄--天生自然python学习笔记:python 用pygame模块制作一个音效播放器

    用 Sound 对象制作一个音效播放器. 应用程序总览 程序在执行后默认会把 WAV 音频文件加载到清单中,单击“播放”按钮可开始 播放,同时显示 “正在播放 xxx 音效”的信息 . 播放过程中,可 ...

  5. Struts2中一个自定义拦截器的使用

    1.自定义的拦截器的类: package it.web.interceptor; import com.opensymphony.xwork2.ActionContext; import com.op ...

  6. 使用Windows Form 制作一个简易资源管理器

    自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始 ...

  7. QT制作一个图片播放器

    前言:使用qt制作了一个简单的图片播放器,可以播放gif.png等格式图片 先来看看播放器的功能(当然是很简陋的,没有很深入的设计): 1.点击图片列表中图片进行播放. 2.自动播放,播放的图片的间隔 ...

  8. 重温WCF之消息拦截与篡改(八)

    我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过借 ...

  9. WCF消息拦截,利用消息拦截做身份验证服务

    本文参考  http://blog.csdn.net/tcjiaan/article/details/8274493  博客而写 添加对信息处理的类 /// <summary> /// 消 ...

随机推荐

  1. swoole udp

    server.php <?php $server = new swoole_server('127.0.0.1', 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); ...

  2. windows8.1的启动目录的路径

    C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\ 或者使用斜杠表示,就像这样: C:/ProgramData/Microsof ...

  3. CoreSight介绍篇

    ARM的嵌入式IDE发展: 1)SDT,英文全称ARM SoftWare Development Kit,是ARM为方便用户在ARM芯片进行应用软件开发而推出的一整套开发工具. 2)ADS,英文全称A ...

  4. linux常用命令:netstat 命令

    netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP ...

  5. Spring 问题总结

    Spring问答Top 25:http://www.importnew.com/15851.html [Java面试五]Spring总结以及在面试中的一些问题.:http://www.cnblogs. ...

  6. Linux基础命令---zip

    zip zip是一种最通用的文件压缩方式,使用于unix.msdos.windows.OS等系统.如果在编译zip时包含bzip 2库,zip现在也支持bzip 2压缩.当将大于4GB的文件添加到存档 ...

  7. [转载]ASP.NET中IsPostBack详解

    1.IsPostBack介绍Page.IsPostBack是一个标志:当前请求是否第一次打开. 调用方法为:Page.IsPostBack或者IsPostBack或者this.IsPostBack或者 ...

  8. python之路----包

    包 包是一种通过使用‘.模块名’来组织python模块名称空间的方式. 1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警 ...

  9. ELK学习笔记之Elasticsearch启动常见错误

    问题出现的环境: OS版本:CentOS-7-x86_64-Minimal-1708 ES版本:elasticsearch-6.2.2 1. max file descriptors [4096] f ...

  10. 冒泡排序法原理讲解及PHP代码示例

    冒泡排序原理 冒泡排序对一个数组里的数字进行排序,把数组里两个相邻的数比较大小,将值小的数放在前面,把大的数往后面放,当然这种排序是升序,即从小到大.举例说明$array = [64, 56, 31, ...