(转)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> /// 消 ...
随机推荐
- Windows下Ionic Android开发环境搭建
转自 http://www.itwap.net/ArticleContent.aspx?id=26 来源: itwap.net 作者: 词略 时间: 2015-4-2 16:57:28 (一)Ioni ...
- 总结《二》MFC中WinMain和CALLBACK
MFC中WinMain和回调函数CALLBACK 一,路线 1.一般普通窗口或控件建立调用的CWnd :: CreateEx函数 2.经过资源对话框创建的即不调用的CWnd ...
- X-UA-Compatible
X-UA-Compatible是神马? X-UA-Compatible是IE8的一个专有<meta>属性,它告诉IE8采用何种IE版本去渲染网页,在html的<head>标签中 ...
- FAFU 1395
动态规划:...翻牌FAFU 1395 动态规划
- WebStorm使用快速入门
WebStorm建立在开源IntelliJ平台之上,JetBrains已经开发和完善了超过15年.其提供了统一的UI,可与许多流行的版本控制系统配合使用,确保在git,GitHub,SVN,Mercu ...
- python-安装,设置环境变量(win10)
python官网: https://www.python.org/ 选择需要的版本下载 下载后安装 我装的是默认位置C:\Python27 打开环境变量设置: 右键电脑--->属性----> ...
- Qt的四个常见的图像叠加模式
Qt的QPainter::CompositionMode提供了多种图像叠加的模式.常见的有QPainter::CompositionMode_SourceOver, QPainter::Composi ...
- silverlight数据绑定
控件绑定 <Grid x:Name="LayoutRoot"> <StackPanel> <ScrollBar x:Name="bar&qu ...
- python之路----面向对象的继承特性
继承 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 class ...
- camera按键采集图像及waitKey的用法
前言 项目需要通过摄像头采集图像并保存,主要是用于后续的摄像头标定.实现过程其实很简单,需要注意一些细节. 系统环境 系统版本:ubuntu16.04:opencv版本:opencv2.4.13:编程 ...