EasyCsharp
来源:互联网 发布:安智市场软件下载 编辑:程序博客网 时间:2024/05/16 15:28
RealProxy实现代理
RealProxy实现 MarshalByRefObject对象的代理
对于MarshalByRefObject
对象,可以使用下面的代码代理,并且对于传递到方法中的ref或out参数都可以正常返回。RemotingServices.ExecuteMessage
传递的参数要求被代理对象是MarshalByRefObject
类型。
Code
using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Runtime.Remoting;using System.Runtime.Remoting.Activation;using System.Runtime.Remoting.Messaging;using System.Runtime.Remoting.Proxies;using System.Text;using System.Threading.Tasks;using SampleCommon;namespace DynamicProxy{ public class DynamicProxy2 { public static void Run() { G.SetLogPreStr("[DynamicProxy2]"); var bird = new Bird(); var proxy = EasyProxy2.NewProxy(bird); proxy.Say(); int a = 2; int b; int c = proxy.Say(ref a, out b); G.Log("a: {0} b:{1} c:{2}", a, b, c); } } public interface ISay { void Say(); int Say(ref int a, out int b); } public class Bird : MarshalByRefObject, ISay { public Bird() { G.Log("this is bird construct"); } public void Say() { G.Log("this is bird say"); } public int Say(ref int a, out int b) { a++; b = 1; return a; } } public class EasyProxy2 : RealProxy { private MarshalByRefObject _target; private EasyProxy2(MarshalByRefObject target) : base(target.GetType()) { _target = target; } public override IMessage Invoke(IMessage msg) { var methodCall = (IMethodCallMessage) msg; G.Log("begin method {0}", methodCall.MethodName); IMethodReturnMessage myIMethodReturnMessage = RemotingServices.ExecuteMessage(_target, methodCall); G.Log("after method {0}", methodCall.MethodName); return myIMethodReturnMessage; } public static T NewProxy<T>(T target) where T : MarshalByRefObject { var easyProxy = new EasyProxy2(target); return (T) easyProxy.GetTransparentProxy(); } }}
Result
RealProxy实现接口代理
这种方法将实现任意对象但需要继承特定接口的对象代理。
Code
using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Remoting;using System.Runtime.Remoting.Messaging;using System.Runtime.Remoting.Proxies;using System.Text;using System.Threading.Tasks;using SampleCommon;namespace DynamicProxy{ public class DynamicProxy3 { public static void Run() { G.SetLogPreStr("[DynamicProxy3]"); var bird = new Bird3(); var proxy = EasyProxy3<ISay>.NewProxy(bird); proxy.Say(); int a = 2; int b; int c = proxy.Say(ref a, out b); G.Log("a: {0} b:{1} c:{2}", a, b, c); } } public class Bird3 : ISay { public Bird3() { G.Log("this is bird construct"); } public void Say() { G.Log("this is bird say"); } public int Say(ref int a, out int b) { a++; b = 1; return a; } } public class EasyProxy3<T> : RealProxy { private object _target; private EasyProxy3(object target) : base(typeof(T)) { _target = target; } public override IMessage Invoke(IMessage msg) { var methodCall = (IMethodCallMessage) msg; G.Log("begin method {0}", methodCall.MethodName); object[] args = null; if (null != methodCall.Args && methodCall.Args.Length > 0) { args = new object[methodCall.Args.Length]; Array.Copy(methodCall.Args, 0, args, 0, methodCall.Args.Length); } var result = methodCall.MethodBase.Invoke(_target, args); G.Log("after method {0}", methodCall.MethodName); return new ReturnMessage(result, args, args == null ? 0 : args.Length, methodCall.LogicalCallContext, methodCall); } public static T NewProxy(T target) { var easyProxy = new EasyProxy3<T>(target); return (T)easyProxy.GetTransparentProxy(); } }}
Result
上面两种方式实现的代理方法均无法对构造函数进行拦截
ProxyAttribute特性拦截
话不多说,详细内容都写在了注释里,被代理类必须继承自ContextBoundObject
,这里给出完整示例。
Code
using System;using System.Collections.Generic;using System.IO.Ports;using System.Linq;using System.Runtime.Remoting;using System.Runtime.Remoting.Activation;using System.Runtime.Remoting.Contexts;using System.Runtime.Remoting.Messaging;using System.Runtime.Remoting.Proxies;using System.Runtime.Remoting.Services;using System.Security.Permissions;using System.Text;using System.Threading.Tasks;using SampleCommon;namespace DynamicProxy{ class DynamicProxy4 { public static void Run() { G.SetLogPreStr("[DynamicProxy4]"); G.Log("begin"); //这里使用的new RayspyObject()并没有真正构建相关对象,而是被代理对象拦截重新构建,因此不要传递参数给其构造函数,无效 var server = new RayspyObject(); server.Say("hello"); G.Log("end"); } } /* * 1.只有需要代理的对象继承自ContextBoundObject时再可以正常拦截,否则无法拦截,即使继承MarshalByRefObject也不行 * 2.特性是针对于类而非对象,因此构造函数中初始化的内容将无法正常传递 */ [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] [RaySpyProxy] public class RayspyObject : ContextBoundObject { public RayspyObject() { G.Log("RayspyObject constructor called"); } public void Say(string str) { G.Log("RayspyObject method Say invoke with msg: " + str); } } [AttributeUsage(AttributeTargets.Class)] [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.Infrastructure)] public class RaySpyProxyAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { MarshalByRefObject obj = base.CreateInstance(serverType); var proxy = new ObjProxy(serverType, obj); return (MarshalByRefObject)proxy.GetTransparentProxy(); } } public class ObjProxy : RealProxy { private MarshalByRefObject _target = null; public ObjProxy(Type type, MarshalByRefObject target) : base(type) { this._target = target; } public override IMessage Invoke(IMessage msg) { var methodCall = (IMethodCallMessage)msg; G.Log("begin call {0}", methodCall.MethodName); var methodConstruct = methodCall as IConstructionCallMessage; IMethodReturnMessage back = null; //构造函数,只有ContextBoundObject(Inherit from MarshalByRefObject)对象才能截获构造函数 if (methodConstruct != null) { RealProxy defaultProxy = RemotingServices.GetRealProxy(_target); //此时_target并没有真正构建 //下面这句是构建_target defaultProxy.InitializeServerObject(methodConstruct); //本类是一个RealProxy,它可通过GetTransparentProxy函数得到透明代理 back = EnterpriseServicesHelper.CreateConstructionReturnMessage(methodConstruct, (MarshalByRefObject) GetTransparentProxy()); } /* * MarshalByRefObject对象就可截获普通的调用消息, * MarshalByRefObject对象告诉编译器,不能将其内部简单的成员函数优化成内联代码, * 这样才能保证函数调用都能截获。 */ else { //可以进行参数验证? back = RemotingServices.ExecuteMessage(_target, methodCall); } G.Log("end call {0}", methodCall.MethodName); return back; } }}
Result
引用
[1] MSDN ProxyAttribute
[2] MSDN RealProxy
[3] .Net中的RealProxy实现AOP
[4] Proxy代理背后的原理
阅读全文
0 0
- EasyCsharp
- String 和StringBuilder的区别
- Host XXX is blocked because of many connection errors, unblock with 'mysqladmin flush-hosts
- 单目/双目与imu的融合(一)
- 死锁现象-Java基础070
- JSP 页面重定向
- EasyCsharp
- Request对象的主要方法
- iOS 从0到1搭建高可用App框架
- Linux 使用pppd和ppp程序进行3G/4G拨号
- 12对象的构造和析构
- LintCode 安排课程
- Zookeeper 安装与配置
- 求知过程之存储过程回滚
- Sublime Text3配置python环境(二)——利用Package Control安装插件