利用.NET Remoting基础架构中的真实代理/透明代理技术实现了不针对具体类型、具体方法的通用方法调用拦截机制
2007-06-15 13:31
1116 查看
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
[align=left]namespace TTester[/align]
[align=left]{[/align]
[align=left] /////////////////////////////////////////////////////////////////////////////////////////////////[/align]
[align=left] public class Calculator : MarshalByRefObject[/align]
[align=left] {[/align]
[align=left] private Calculator() { }[/align]
[align=left] [/align]
[align=left] public static Calculator CreateInstance()[/align]
[align=left] {[/align]
[align=left] MessageChainProxy realProxy = new MessageChainProxy(new Calculator());[/align]
[align=left] realProxy.AppendSinkType(typeof(LogAspect));[/align]
[align=left] Object transparentProxy = realProxy.GetTransparentProxy();[/align]
[align=left] return (Calculator)transparentProxy;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public int Add(int x, int y)[/align]
[align=left] {[/align]
[align=left] return x + y;[/align]
[align=left] }[/align]
}
/////////////////////////////////////////////////////////////////////////////////////////////////
[align=left] public class MessageChainProxy : RealProxy[/align]
[align=left] {[/align]
[align=left] private class TerminatorSink : IMessageSink[/align]
[align=left] {[/align]
[align=left] private MarshalByRefObject m_target;[/align]
[align=left] [/align]
[align=left] public TerminatorSink(MarshalByRefObject target)[/align]
[align=left] {[/align]
[align=left] this.m_target = target;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] #region IMessageSink Members[/align]
[align=left] [/align]
[align=left] public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)[/align]
[align=left] {[/align]
[align=left] throw new Exception("The method or operation is not implemented.");[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public IMessageSink NextSink[/align]
[align=left] {[/align]
[align=left] get { return null; }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public IMessage SyncProcessMessage(IMessage msg)[/align]
[align=left] {[/align]
[align=left] return RemotingServices.ExecuteMessage(m_target, msg as IMethodCallMessage);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] #endregion[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] private MarshalByRefObject m_target;[/align]
[align=left] private IMessageSink headSink;[/align]
[align=left] [/align]
[align=left] public MessageChainProxy(MarshalByRefObject target)[/align]
[align=left] : base(target.GetType())[/align]
[align=left] {[/align]
[align=left] this.m_target = target;[/align]
[align=left] headSink = new TerminatorSink(m_target);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public override IMessage Invoke(IMessage msg)[/align]
[align=left] {[/align]
[align=left] return headSink.SyncProcessMessage(msg);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public void AppendSinkType(Type sinkType)[/align]
[align=left] {[/align]
[align=left] object[] ctorArgs = new object[] { headSink };[/align]
[align=left] IMessageSink newSink = (MessageSinkBase)Activator.CreateInstance(sinkType, ctorArgs);[/align]
[align=left] headSink = newSink;[/align]
[align=left] }[/align]
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
[align=left] public abstract class MessageSinkBase : IMessageSink[/align]
[align=left] {[/align]
[align=left] private readonly IMessageSink m_nextSink;[/align]
[align=left] [/align]
[align=left] public MessageSinkBase(IMessageSink nextSink)[/align]
[align=left] {[/align]
[align=left] m_nextSink = nextSink;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] #region IMessageSink Members[/align]
[align=left] [/align]
[align=left] public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)[/align]
[align=left] {[/align]
[align=left] return m_nextSink.AsyncProcessMessage(msg, replySink);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public IMessageSink NextSink[/align]
[align=left] {[/align]
[align=left] get { return m_nextSink; }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public abstract IMessage SyncProcessMessage(IMessage msg);[/align]
[align=left] [/align]
[align=left] #endregion[/align]
}
//////////////////////////////////////////////////////////////////////////////////////////////////
[align=left] public class LogAspect : MessageSinkBase[/align]
[align=left] {[/align]
[align=left] public LogAspect(IMessageSink nextSink)[/align]
[align=left] : base(nextSink)[/align]
[align=left] {[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public override IMessage SyncProcessMessage(IMessage msg)[/align]
[align=left] {[/align]
[align=left] IMethodCallMessage callMsg = msg as IMethodCallMessage;[/align]
[align=left] [/align]
[align=left] DateTime callTime = DateTime.Now;[/align]
[align=left] IMessage returnMsg = NextSink.SyncProcessMessage(msg);[/align]
[align=left] DateTime retTime = DateTime.Now;[/align]
[align=left] IMethodReturnMessage retMsg = returnMsg as IMethodReturnMessage;[/align]
[align=left] [/align]
[align=left] TimeSpan tspan = callTime.Subtract(retTime);[/align]
[align=left] string[] strs = callMsg.TypeName.Split(new char[] { ',', '.' });[/align]
[align=left] string clsName = null;[/align]
[align=left] if (strs.Length >= 2)[/align]
[align=left] {[/align]
[align=left] clsName = strs[1];[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] Console.WriteLine("[" + callTime + "] " +[/align]
[align=left] clsName +[/align]
[align=left] "." +[/align]
[align=left] callMsg.MethodName +[/align]
[align=left] "(" +[/align]
[align=left] callMsg.InArgs[0] +[/align]
[align=left] "," +[/align]
[align=left] callMsg.InArgs[1] +[/align]
[align=left] ") " +[/align]
[align=left] "-(" +[/align]
[align=left] tspan.TotalMilliseconds * 1000000 +[/align]
[align=left] "ns)-> " +[/align]
[align=left] retMsg.ReturnValue[/align]
[align=left] );[/align]
[align=left] [/align]
[align=left] return returnMsg;[/align]
[align=left] }[/align]
}
}
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
[align=left]namespace TTester[/align]
[align=left]{[/align]
[align=left] /////////////////////////////////////////////////////////////////////////////////////////////////[/align]
[align=left] public class Calculator : MarshalByRefObject[/align]
[align=left] {[/align]
[align=left] private Calculator() { }[/align]
[align=left] [/align]
[align=left] public static Calculator CreateInstance()[/align]
[align=left] {[/align]
[align=left] MessageChainProxy realProxy = new MessageChainProxy(new Calculator());[/align]
[align=left] realProxy.AppendSinkType(typeof(LogAspect));[/align]
[align=left] Object transparentProxy = realProxy.GetTransparentProxy();[/align]
[align=left] return (Calculator)transparentProxy;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public int Add(int x, int y)[/align]
[align=left] {[/align]
[align=left] return x + y;[/align]
[align=left] }[/align]
}
/////////////////////////////////////////////////////////////////////////////////////////////////
[align=left] public class MessageChainProxy : RealProxy[/align]
[align=left] {[/align]
[align=left] private class TerminatorSink : IMessageSink[/align]
[align=left] {[/align]
[align=left] private MarshalByRefObject m_target;[/align]
[align=left] [/align]
[align=left] public TerminatorSink(MarshalByRefObject target)[/align]
[align=left] {[/align]
[align=left] this.m_target = target;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] #region IMessageSink Members[/align]
[align=left] [/align]
[align=left] public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)[/align]
[align=left] {[/align]
[align=left] throw new Exception("The method or operation is not implemented.");[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public IMessageSink NextSink[/align]
[align=left] {[/align]
[align=left] get { return null; }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public IMessage SyncProcessMessage(IMessage msg)[/align]
[align=left] {[/align]
[align=left] return RemotingServices.ExecuteMessage(m_target, msg as IMethodCallMessage);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] #endregion[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] private MarshalByRefObject m_target;[/align]
[align=left] private IMessageSink headSink;[/align]
[align=left] [/align]
[align=left] public MessageChainProxy(MarshalByRefObject target)[/align]
[align=left] : base(target.GetType())[/align]
[align=left] {[/align]
[align=left] this.m_target = target;[/align]
[align=left] headSink = new TerminatorSink(m_target);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public override IMessage Invoke(IMessage msg)[/align]
[align=left] {[/align]
[align=left] return headSink.SyncProcessMessage(msg);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public void AppendSinkType(Type sinkType)[/align]
[align=left] {[/align]
[align=left] object[] ctorArgs = new object[] { headSink };[/align]
[align=left] IMessageSink newSink = (MessageSinkBase)Activator.CreateInstance(sinkType, ctorArgs);[/align]
[align=left] headSink = newSink;[/align]
[align=left] }[/align]
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
[align=left] public abstract class MessageSinkBase : IMessageSink[/align]
[align=left] {[/align]
[align=left] private readonly IMessageSink m_nextSink;[/align]
[align=left] [/align]
[align=left] public MessageSinkBase(IMessageSink nextSink)[/align]
[align=left] {[/align]
[align=left] m_nextSink = nextSink;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] #region IMessageSink Members[/align]
[align=left] [/align]
[align=left] public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)[/align]
[align=left] {[/align]
[align=left] return m_nextSink.AsyncProcessMessage(msg, replySink);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public IMessageSink NextSink[/align]
[align=left] {[/align]
[align=left] get { return m_nextSink; }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public abstract IMessage SyncProcessMessage(IMessage msg);[/align]
[align=left] [/align]
[align=left] #endregion[/align]
}
//////////////////////////////////////////////////////////////////////////////////////////////////
[align=left] public class LogAspect : MessageSinkBase[/align]
[align=left] {[/align]
[align=left] public LogAspect(IMessageSink nextSink)[/align]
[align=left] : base(nextSink)[/align]
[align=left] {[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] public override IMessage SyncProcessMessage(IMessage msg)[/align]
[align=left] {[/align]
[align=left] IMethodCallMessage callMsg = msg as IMethodCallMessage;[/align]
[align=left] [/align]
[align=left] DateTime callTime = DateTime.Now;[/align]
[align=left] IMessage returnMsg = NextSink.SyncProcessMessage(msg);[/align]
[align=left] DateTime retTime = DateTime.Now;[/align]
[align=left] IMethodReturnMessage retMsg = returnMsg as IMethodReturnMessage;[/align]
[align=left] [/align]
[align=left] TimeSpan tspan = callTime.Subtract(retTime);[/align]
[align=left] string[] strs = callMsg.TypeName.Split(new char[] { ',', '.' });[/align]
[align=left] string clsName = null;[/align]
[align=left] if (strs.Length >= 2)[/align]
[align=left] {[/align]
[align=left] clsName = strs[1];[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] Console.WriteLine("[" + callTime + "] " +[/align]
[align=left] clsName +[/align]
[align=left] "." +[/align]
[align=left] callMsg.MethodName +[/align]
[align=left] "(" +[/align]
[align=left] callMsg.InArgs[0] +[/align]
[align=left] "," +[/align]
[align=left] callMsg.InArgs[1] +[/align]
[align=left] ") " +[/align]
[align=left] "-(" +[/align]
[align=left] tspan.TotalMilliseconds * 1000000 +[/align]
[align=left] "ns)-> " +[/align]
[align=left] retMsg.ReturnValue[/align]
[align=left] );[/align]
[align=left] [/align]
[align=left] return returnMsg;[/align]
[align=left] }[/align]
}
}
相关文章推荐
- 利用泛型和反射编写通用基础类型转换方法
- 【Android开发经验】利用反射机制,获取类的字段、方法、并实现简单调用
- java反射机制(2)- 实践:反射机制+动态代理实现模拟RMI远程方法调用
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- 利用动态代理实现通用存储过程的调用
- 利用反射机制,获取类的字段、方法、并实现简单调用
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- java中利用反射机制实现调用给定为字符串的方法名
- java中利用反射机制实现调用给定为字符串的方法名
- 真实案例:嘉为科技利用微软最新的虚拟化技术, 完成基础架构平台和邮件服务器的迁移
- 反射实现方法调用(1):执行机制
- ios 利用runtime 机制 交换系统内部方法的实现
- puppet 利用 facter, 实现不同主机调用不同变量方法
- 类型:Jquery;问题:jquery调用后台带参数方法;结果:利用JQuery的$.ajax()可以很方便的调用asp.net的后台方法。
- Android设计模式之动态代理,实现方法拦截功能
- iOS JS 交互之利用系统JSContext实现 JS调用OC方法以及Objective-C调用JavaScript方法
- 主流数据库之间对SQL:2003标准的不同实现方法比较(第六部分 基础数据类型之BOOLEAN)
- spring动态代理的实现原理InvocationHandler中invoke()方法的调用问题
- 数据库通用基础实现技术---多进程共享信息
- 利用反射实现对象调用方法