(转)C#制作一个消息拦截器
首先,我们先要制作一个自定义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 ,然后让我们去做些新环境应该做的事。
- /// <summary>
- /// Some class if you want to intercept,you must mark this attribute.
- /// </summary>
- public class InterceptAttribute : Attribute, IContextAttribute
- {
- public InterceptAttribute()
- {
- Console.WriteLine(" Call 'InterceptAttribute' - 'Constructor' ");
- }
- public void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
- {
- ctorMsg.ContextProperties.Add(new InterceptProperty());
- }
- public bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
- {
- InterceptProperty interceptObject = ctx.GetProperty("Intercept") as InterceptProperty;
- return interceptObject != null;
- }
- }
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()方法需要我们去实现,主要作用是得到一个消息池的对象。
好,话不多说,直接贴代码:
- //IContributeObjectSink,IContributeEnvoySink,IContributeClientContextSink,IContributeServerContextSink
- public class InterceptProperty:IContextProperty,IContributeObjectSink
- {
- public InterceptProperty()
- {
- Console.WriteLine(" Call 'InterceptProperty' - 'Constructor' ");
- }
- public string Name {
- get
- {
- return "Intercept";
- }
- }
- public void Freeze(Context newContext)
- {
- }
- public bool IsNewContextOK(Context newCtx)
- {
- var result = newCtx.GetProperty("Intercept");
- return result!=null;
- //return false;
- }
- public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
- {
- InterceptSink interceptSink = new InterceptSink(nextSink);
- return interceptSink;
- }
- }
简单解释一下,IsNewContextOK() 函数中,我主要是在当前新的上下文中获得我想要的Intercept属性,正常情况下,系统会构造出InterceptProperty对象,GetProperty()函数就是get出Name属性是否匹配,如果匹配则return true,否则异常。
另外的GetObjectSink方法则是得到一个InterceptSink的对象,下一节我会实现InterceptSink类。
之前为InterceptAttribute的上下文环境添加了“Intercept”属性(InterceptProperty),正因为InterceptProperty继承了IContributeObjectSink,所以我们要实现GetObjectSink(),继而我们要创建一个继承ImessageSink的类来作为返回值。
这样就引发出了InterceptSink类的实现:
- public class InterceptSink : IMessageSink
- {
- private IMessageSink nextSink = null;
- public IMessageSink NextSink
- {
- get { return nextSink; }
- }
- public InterceptSink(IMessageSink nextSink)
- {
- Console.WriteLine(" Call 'InterceptSink' - 'Constructor' ");
- this.nextSink = nextSink;
- }
- public IMessage SyncProcessMessage(IMessage msg)
- {
- Console.WriteLine("method_name: " + msg.Properties["__MethodName"].ToString());
- IMessage returnMsg = nextSink.SyncProcessMessage(msg);
- return returnMsg;
- }
- public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
- {
- return null;
- }
- }
核心方法是:SyncProcessMessage(Imessage msg)
传入参数msg中,我们可以找到调用对象方法的相应数据。
ok,我们拦截器基本构造完成,接下来我来告诉大家如何去使用。
注意一个问题,object拦截器我们要拦截什么,那么我们就要在需要拦截的类上面做手脚了。
首先,创建我们需要被拦截的类。
然后,我们再对类进行相应的包装:
1、该类要标记InterceptAttribute属性
2、该类要继承ContextBoundObject,只有继承ContextBoundObject的类,vs才能知道该类需要访问Context,这样标记的InterceptAttribute才有效。
- /// <summary>
- /// If you want to add the interceptpool on this class , the class need to do:
- /// 1、inherited form ContextBoundObject.
- /// 2、mark the InterceptAttribute.
- /// </summary>
- [Intercept]
- public class SimonDemo:ContextBoundObject
- {
- public SimonDemo()
- {
- Console.WriteLine(" Call 'SimonDemo' - 'Constructor' ");
- }
- public void Operate1()
- {
- Console.WriteLine("Call 'SimonDemo' - 'Operate1' ");
- }
- }
然后,我们在Main函数中创建一个该类的对象,并进行调用方法。
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("Call Main ..");
- SimonDemo simon = new SimonDemo();
- simon.Operate1();
- Console.WriteLine("exit Main ..");
- Console.Read();
- }
- }
这样,通过调试,我们就可以看出拦截器都拦截出了什么
接下来是运行结果:
这样可以看出我的程序拦截,并输出了调用函数的名字。
(转)C#制作一个消息拦截器的更多相关文章
- C#制作一个消息拦截器(intercept)1
首先,我们先要制作一个自己定义Attribute,让他能够具有上下文读取功能,所以我们这个Attribute类要同一时候继承Attribute和IContextAttribute. 接口IContex ...
- C# 通过Attribute制作的一个消息拦截器
首先,我们先要制作一个自己定义Attribute,让他能够具有上下文读取功能,所以我们这个Attribute类要同一时候继承Attribute和IContextAttribute. 接口IContex ...
- 开发openfire 消息拦截器插件PacketInterceptor
开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承PacketInterceptor包拦截类,然后在initializelPlugin()方法中注册拦截器,就可以实现inter ...
- 吴裕雄--天生自然python学习笔记:python 用pygame模块制作一个音效播放器
用 Sound 对象制作一个音效播放器. 应用程序总览 程序在执行后默认会把 WAV 音频文件加载到清单中,单击“播放”按钮可开始 播放,同时显示 “正在播放 xxx 音效”的信息 . 播放过程中,可 ...
- Struts2中一个自定义拦截器的使用
1.自定义的拦截器的类: package it.web.interceptor; import com.opensymphony.xwork2.ActionContext; import com.op ...
- 使用Windows Form 制作一个简易资源管理器
自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始 ...
- QT制作一个图片播放器
前言:使用qt制作了一个简单的图片播放器,可以播放gif.png等格式图片 先来看看播放器的功能(当然是很简陋的,没有很深入的设计): 1.点击图片列表中图片进行播放. 2.自动播放,播放的图片的间隔 ...
- 重温WCF之消息拦截与篡改(八)
我们知道,在WCF中,客户端对服务操作方法的每一次调用,都可以被看作是一条消息,而且,可能我们还会有一个疑问:如何知道客户端与服务器通讯过程中,期间发送和接收的SOAP是什么样子.当然,也有人是通过借 ...
- WCF消息拦截,利用消息拦截做身份验证服务
本文参考 http://blog.csdn.net/tcjiaan/article/details/8274493 博客而写 添加对信息处理的类 /// <summary> /// 消 ...
随机推荐
- C#中DataTable
.C#中DataTable技术学习 2009-09-10 14:37:18 阅读1496 评论0 字号:大中小 订阅 . 1.在DataTable中执行DataTable.Select(" ...
- mov指令
一.规定 1.立即数不能作为目的操作数,如mov 110H,AX 2.立即数不能直接传给段寄存器,如mov DS,110H 2.两个操作数不能同时为段寄存器,如mov ES,DS 3.两个操作数不能同 ...
- Repeater 控件使用总结
关于Repeater控件使用的一些总结,希望能对将来有机会看到这篇日志的同事有所帮助.也是为了在自己开发有所遗忘的时候能够参考一下.前言:Repeater是一个迭代控件,什么是迭代控件呢?书本上的 ...
- kafka监控工具之一--kafka-manager
部署环境 jdk7 kafka_2.10-0.9.0.1 xshell4 rhel-server-6.5 kafka-manager 是功能比较多的kafka管控工具. 安装方法一 安装方法二 步骤一 ...
- Linux其他:环境变量配置
计算机==>右键==>属性==>高级系统设置==>环境变量==> 系统变量path后面+';python路径名
- Linux基础命令---mktemp
mktemp 创建临时文件或者目录,这样的创建方式是安全的.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法 mk ...
- SNMP学习笔记之SNMP的安装及Python的调用
0x00 概述 本文是介绍SNMP在Windows和Linux(Ubuntu)下的安装,以及通过Python调用其接口的文章. 0x01 开发环境 Python 3.5.1 Windows 10 64 ...
- Redis计算地理位置距离-GeoHash
Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」.美团和饿了么「附近的餐馆」这样的功能了. 地图元素的位置数据使用二 ...
- PHP多进程处理并行处理任务实例(转,备用)
本文目的本文通过例子讲解linux环境下,使用php进行并发任务处理,以及如何通过pipe用于进程间的数据同步.PHP多进程通过pcntl_XXX系列函数使用多进程功能.注意:pcntl_XXX只能运 ...
- QtQuickcontrols2控件使用参考
随着Qt的版本升级,其自带的controls控件库也不断升级,目前已经到了2.3的版本.本文通过解读Qt自带的gallery例程,说明新版本controls控件库的相关特性.其具体位置于: 因为相关的 ...