![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#11
| |||
| |||
|
|
You can send a mail directly to me with an attachment. Alternatively I guess you could attach a zip to your post, I do not know if the NG will accept that but it is worth a try. -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:5426E437-D8FF-4A73-A47C-4C341AFEEEE1 (AT) microsoft (DOT) com... sure thing; where do I post this at? "Chris Taylor" wrote: Hi Richard, Base on your last description and the one line of code, it sounds like you are using the cross domain remotinging therefore this is not purely local ie. local being in the same AppDomain in a different Context to support interception. Could you send a small and concise code sample of what you are trying to do, with some comments pointing out your sticking points. -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:8A5F32D3-5CAC-45A6-B4A0-26CAB5F4C12E (AT) microsoft (DOT) com... Hi Chris, Hmm... It seems to me that the actual proxy class can simply intercept the construction message as the class derives from ContextBoundObject. That solves the hackish createinstance code. But even still, what you are providing is still server side! That is, MyProxy would actually reside in the server domain, not the client domain! That is the reason to override createproxy of the proxyattribute class! Why is the serverobject parameter of createproxy always null? What am I missing? i.e Object wobject = mServerDomain.CreateInstanceAndUnwrap(...) createinstance will give a realproxy to intercept calls in the server domain. Now I want to trap calls in the client domain... when calling methods on wObject. The createproxy of proxyattribute is just great for that, but I can't seem to get to the serverobject; I only have an objref to work with... or is that all I need? "Chris Taylor" wrote: Hi, In that case I would suggest you go the route I initially provided. I understand the desire to auto magically intercept the new operator and have the instances proxied. For this to work you should create your custom proxy in the CreateInstance member of your ProxyAttribute class, except that we have no public way of creating uninitialized objects, which would require you to use some very nasty reflection to invoke some internal functionality in the framework. I am going to get flamed for this, but here is a quick example of the type of reflection you would require to do this. [AttributeUsage(AttributeTargets.Class)] public class MyProxyAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { Type remotingServicesType = typeof(RemotingServices); MethodInfo mi = remotingServicesType.GetMethod( "AllocateUninitializedObject", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[]{typeof(Type)}, null); MarshalByRefObject o = mi.Invoke(null, new object[] { serverType }) as MarshalByRefObject; return MyProxy.CreateProxy<MarshalByRefObject>(o); } } Using the above MyProxyAttribute the Invoke method on the MyProxy RealProxy from my original sample will be called. Now you will also need to handle the ConstructorCallMessage because even that is now intercepted. Again, I have done this in type of interception in production and I use something very similar to what I showed initially. The reflection is high risk for compatibility for newer framework version (I can site examples of things that have broken!) and to be honest I prefer the more explicit code showing that I expect this instance to be proxied. In fact in the implementation I have our objects all have provate constructors and the call to create the proxy is passed the type and the instance is created internally. But that is my 2c... -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:56CCD049-0C8E-4F8A-887B-3C1E52BDF0A8 (AT) microsoft (DOT) com... Complete local; remoting can be applied later... I need to be able to intercept calls on both the client and server sides (locally, not through remoting...) "Chris Taylor" wrote: Hi, What is it that you are trying to achieve? Do you just required local interception of function calls or do you need this for a remoting scenario that requires custom proxying? -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:75757411-E362-45D0-B484-ADB13E7DE64C (AT) microsoft (DOT) com... Of course, that works... But I am trying to get this to work by using the ProxyAttribute class on ProxyMe for example. The CreateProxy method of the ProxyAttribute class does get called on the proper side (i.e. client), but I am unable to reach the transparent proxy from there... Thanks "Chris Taylor" wrote: Hi, What you can do is create a static method on your RealProxy derived class which accepts the object instance that you want to proxy. This method in turn calls a private constructor with the instance which passes the type of the instance to the RealProxy base class constructor and stores the instance in a member variable of your proxy class which can be accessed from your override of the Invoke method. May be some code would make this clearer... NB I have not added any error checking etc. class Program { static void Main(string[] args) { // The instance of the object that we will be proxying ProxyMe targetObject = new ProxyMe(); // Create the actual proxy object using MyProxy.CreateProxy ProxyMe proxy = MyProxy.CreateProxy<ProxyMe>(targetObject); // Call the method on the proxy proxy.Add(1, 3); } } // Simple class that we will be using to test the proxying public class ProxyMe : MarshalByRefObject { public int Add(int x, int y) { return x + y; } } // Example of a simple RealProxy that will take an instance of // an object and create an proxy for the instance. public class MyProxy : RealProxy { // Store the instance that is being proxied private MarshalByRefObject _instance; // Private constuctor that accepts an instance of a MBRO private MyProxy(MarshalByRefObject instance) : base(instance.GetType()) { _instance = instance; } // A basic factory method to support proxy creation // Definately need some error checking here.... public static T CreateProxy<T>(MarshalByRefObject instance) where T : MarshalByRefObject { MyProxy proxy = new MyProxy(instance); return proxy.GetTransparentProxy() as T; } // This is where the method calls on the proxy object end up // This implementation just passes the cal on to the target object // again no error checking or message type checking for that matter public override IMessage Invoke(IMessage msg) { // do some cool stuff before the target method is called return RemotingServices.ExecuteMessage(_instance, msg as IMethodCallMessage); } } Best Regards, -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:B974C716-9C9C-41D0-8BB5-3DC5FB4AB76E (AT) microsoft (DOT) com... Hello, I am trying to figure out how I can intercept calls made onto objects using the RealProxy mechanism. Works fine on the server side; but am unable to figure out how to do it on the client side. That is, if I understand correctly, I need to overload CreateProxy from the RealProxy class, which would allow me to create a proxy of my own... easy enough --- BUT how to I get to know which object this refers to once in a call with the invoke method? Any help would be greatly appreciated! |
#12
| |||
| |||
|
|
Hello Chris, So here it is, I hopefully did not make this too confusing; The problem I have resides in the CreateProxy of the MyProxyAttribute class. How do I get to maintain the server reference? using System; using System.Reflection; using System.Collections.Generic; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Channels; namespace ContextInterception { [MyProxy] class MyClass : ContextBoundObject { public override object InitializeLifetimeService() { return null; // base.InitializeLifetimeService(); } public void SayHi() { Console.WriteLine(AppDomain.CurrentDomain.Friendly Name + ": MyClass.SayHi"); } } class MyProxy: RealProxy { public MyProxy(Type type) : base(type) { } RealProxy mRealProxy; public MyProxy(Type type, RealProxy realProxy) : base(type) { mRealProxy = realProxy; } public override IMessage Invoke(IMessage msg) { if (msg is IConstructionCallMessage) { Console.WriteLine(AppDomain.CurrentDomain.Friendly Name + ": MyProxy.Invoke (construction call)"); IConstructionCallMessage ctorCallMessage = msg as IConstructionCallMessage; IMessage wReturnMessage = InitializeServerObject(ctorCallMessage); return wReturnMessage; } Console.WriteLine(AppDomain.CurrentDomain.Friendly Name + ": MyProxy.Invoke (method call)"); if (mRealProxy != null) { return mRealProxy.Invoke(msg); } return ChannelServices.SyncDispatchMessage(msg); } } class MyProxyAttribute: ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { Console.WriteLine(AppDomain.CurrentDomain.Friendly Name + ": MyProxyAttribute.CreateInstance"); MyProxy wMyProxy = new MyProxy(serverType); return wMyProxy.GetTransparentProxy() as MarshalByRefObject; } public override RealProxy CreateProxy(ObjRef objRef, Type serverType, object serverObject, Context serverContext) { Console.WriteLine(AppDomain.CurrentDomain.Friendly Name + ": MyProxyAttribute.CreateProxy"); if (Program.OverrideCreateProxy == false) { return base.CreateProxy(objRef, serverType, serverObject, serverContext); } // // This is the piece of code that I can't figure out // RealProxy wRealProxy = base.CreateProxy(objRef, serverType, serverObject, serverContext); MyProxy wMyProxy = new MyProxy(serverType, wRealProxy); if (serverContext != null) { RealProxy.SetStubData(wMyProxy, serverContext); } if ((!serverType.IsMarshalByRef) && (serverContext == null)) { throw new RemotingException("Bad Type for CreateProxy"); } return wMyProxy; // // End of piece of code I can't figure out // } } class Program { static public Boolean OverrideCreateProxy; static void Main(string[] args) { AppDomain wAppDomain = AppDomain.CreateDomain("Remote"); Console.WriteLine("|--"); Console.WriteLine("|-- Case 1, default MyProxyAttribute.CreateProxy"); Console.WriteLine("|--"); MyClass wMyClass = wAppDomain.CreateInstanceAndUnwrap(Assembly.GetEnt ryAssembly().GetName().FullName, typeof(MyClass).FullName) as MyClass; wMyClass.SayHi(); OverrideCreateProxy = true; Console.WriteLine("|--"); Console.WriteLine("|-- Case 2, overriden MyProxyAttribute.CreateProxy"); Console.WriteLine("|--"); wMyClass = wAppDomain.CreateInstanceAndUnwrap(Assembly.GetEnt ryAssembly().GetName().FullName, typeof(MyClass).FullName) as MyClass; wMyClass.SayHi(); } } } "Chris Taylor" wrote: You can send a mail directly to me with an attachment. Alternatively I guess you could attach a zip to your post, I do not know if the NG will accept that but it is worth a try. -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:5426E437-D8FF-4A73-A47C-4C341AFEEEE1 (AT) microsoft (DOT) com... sure thing; where do I post this at? "Chris Taylor" wrote: Hi Richard, Base on your last description and the one line of code, it sounds like you are using the cross domain remotinging therefore this is not purely local ie. local being in the same AppDomain in a different Context to support interception. Could you send a small and concise code sample of what you are trying to do, with some comments pointing out your sticking points. -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:8A5F32D3-5CAC-45A6-B4A0-26CAB5F4C12E (AT) microsoft (DOT) com... Hi Chris, Hmm... It seems to me that the actual proxy class can simply intercept the construction message as the class derives from ContextBoundObject. That solves the hackish createinstance code. But even still, what you are providing is still server side! That is, MyProxy would actually reside in the server domain, not the client domain! That is the reason to override createproxy of the proxyattribute class! Why is the serverobject parameter of createproxy always null? What am I missing? i.e Object wobject = mServerDomain.CreateInstanceAndUnwrap(...) createinstance will give a realproxy to intercept calls in the server domain. Now I want to trap calls in the client domain... when calling methods on wObject. The createproxy of proxyattribute is just great for that, but I can't seem to get to the serverobject; I only have an objref to work with... or is that all I need? "Chris Taylor" wrote: Hi, In that case I would suggest you go the route I initially provided. I understand the desire to auto magically intercept the new operator and have the instances proxied. For this to work you should create your custom proxy in the CreateInstance member of your ProxyAttribute class, except that we have no public way of creating uninitialized objects, which would require you to use some very nasty reflection to invoke some internal functionality in the framework. I am going to get flamed for this, but here is a quick example of the type of reflection you would require to do this. [AttributeUsage(AttributeTargets.Class)] public class MyProxyAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { Type remotingServicesType = typeof(RemotingServices); MethodInfo mi = remotingServicesType.GetMethod( "AllocateUninitializedObject", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[]{typeof(Type)}, null); MarshalByRefObject o = mi.Invoke(null, new object[] { serverType }) as MarshalByRefObject; return MyProxy.CreateProxy<MarshalByRefObject>(o); } } Using the above MyProxyAttribute the Invoke method on the MyProxy RealProxy from my original sample will be called. Now you will also need to handle the ConstructorCallMessage because even that is now intercepted. Again, I have done this in type of interception in production and I use something very similar to what I showed initially. The reflection is high risk for compatibility for newer framework version (I can site examples of things that have broken!) and to be honest I prefer the more explicit code showing that I expect this instance to be proxied. In fact in the implementation I have our objects all have provate constructors and the call to create the proxy is passed the type and the instance is created internally. But that is my 2c... -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:56CCD049-0C8E-4F8A-887B-3C1E52BDF0A8 (AT) microsoft (DOT) com... Complete local; remoting can be applied later... I need to be able to intercept calls on both the client and server sides (locally, not through remoting...) "Chris Taylor" wrote: Hi, What is it that you are trying to achieve? Do you just required local interception of function calls or do you need this for a remoting scenario that requires custom proxying? -- |
#13
| |||
| |||
|
|
You can send a mail directly to me with an attachment. Alternatively I guess you could attach a zip to your post, I do not know if the NG will accept that but it is worth a try. -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:5426E437-D8FF-4A73-A47C-4C341AFEEEE1 (AT) microsoft (DOT) com... sure thing; where do I post this at? "Chris Taylor" wrote: Hi Richard, Base on your last description and the one line of code, it sounds like you are using the cross domain remotinging therefore this is not purely local ie. local being in the same AppDomain in a different Context to support interception. Could you send a small and concise code sample of what you are trying to do, with some comments pointing out your sticking points. -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:8A5F32D3-5CAC-45A6-B4A0-26CAB5F4C12E (AT) microsoft (DOT) com... Hi Chris, Hmm... It seems to me that the actual proxy class can simply intercept the construction message as the class derives from ContextBoundObject. That solves the hackish createinstance code. But even still, what you are providing is still server side! That is, MyProxy would actually reside in the server domain, not the client domain! That is the reason to override createproxy of the proxyattribute class! Why is the serverobject parameter of createproxy always null? What am I missing? i.e Object wobject = mServerDomain.CreateInstanceAndUnwrap(...) createinstance will give a realproxy to intercept calls in the server domain. Now I want to trap calls in the client domain... when calling methods on wObject. The createproxy of proxyattribute is just great for that, but I can't seem to get to the serverobject; I only have an objref to work with... or is that all I need? "Chris Taylor" wrote: Hi, In that case I would suggest you go the route I initially provided. I understand the desire to auto magically intercept the new operator and have the instances proxied. For this to work you should create your custom proxy in the CreateInstance member of your ProxyAttribute class, except that we have no public way of creating uninitialized objects, which would require you to use some very nasty reflection to invoke some internal functionality in the framework. I am going to get flamed for this, but here is a quick example of the type of reflection you would require to do this. [AttributeUsage(AttributeTargets.Class)] public class MyProxyAttribute : ProxyAttribute { public override MarshalByRefObject CreateInstance(Type serverType) { Type remotingServicesType = typeof(RemotingServices); MethodInfo mi = remotingServicesType.GetMethod( "AllocateUninitializedObject", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[]{typeof(Type)}, null); MarshalByRefObject o = mi.Invoke(null, new object[] { serverType }) as MarshalByRefObject; return MyProxy.CreateProxy<MarshalByRefObject>(o); } } Using the above MyProxyAttribute the Invoke method on the MyProxy RealProxy from my original sample will be called. Now you will also need to handle the ConstructorCallMessage because even that is now intercepted. Again, I have done this in type of interception in production and I use something very similar to what I showed initially. The reflection is high risk for compatibility for newer framework version (I can site examples of things that have broken!) and to be honest I prefer the more explicit code showing that I expect this instance to be proxied. In fact in the implementation I have our objects all have provate constructors and the call to create the proxy is passed the type and the instance is created internally. But that is my 2c... -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:56CCD049-0C8E-4F8A-887B-3C1E52BDF0A8 (AT) microsoft (DOT) com... Complete local; remoting can be applied later... I need to be able to intercept calls on both the client and server sides (locally, not through remoting...) "Chris Taylor" wrote: Hi, What is it that you are trying to achieve? Do you just required local interception of function calls or do you need this for a remoting scenario that requires custom proxying? -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:75757411-E362-45D0-B484-ADB13E7DE64C (AT) microsoft (DOT) com... Of course, that works... But I am trying to get this to work by using the ProxyAttribute class on ProxyMe for example. The CreateProxy method of the ProxyAttribute class does get called on the proper side (i.e. client), but I am unable to reach the transparent proxy from there... Thanks "Chris Taylor" wrote: Hi, What you can do is create a static method on your RealProxy derived class which accepts the object instance that you want to proxy. This method in turn calls a private constructor with the instance which passes the type of the instance to the RealProxy base class constructor and stores the instance in a member variable of your proxy class which can be accessed from your override of the Invoke method. May be some code would make this clearer... NB I have not added any error checking etc. class Program { static void Main(string[] args) { // The instance of the object that we will be proxying ProxyMe targetObject = new ProxyMe(); // Create the actual proxy object using MyProxy.CreateProxy ProxyMe proxy = MyProxy.CreateProxy<ProxyMe>(targetObject); // Call the method on the proxy proxy.Add(1, 3); } } // Simple class that we will be using to test the proxying public class ProxyMe : MarshalByRefObject { public int Add(int x, int y) { return x + y; } } // Example of a simple RealProxy that will take an instance of // an object and create an proxy for the instance. public class MyProxy : RealProxy { // Store the instance that is being proxied private MarshalByRefObject _instance; // Private constuctor that accepts an instance of a MBRO private MyProxy(MarshalByRefObject instance) : base(instance.GetType()) { _instance = instance; } // A basic factory method to support proxy creation // Definately need some error checking here.... public static T CreateProxy<T>(MarshalByRefObject instance) where T : MarshalByRefObject { MyProxy proxy = new MyProxy(instance); return proxy.GetTransparentProxy() as T; } // This is where the method calls on the proxy object end up // This implementation just passes the cal on to the target object // again no error checking or message type checking for that matter public override IMessage Invoke(IMessage msg) { // do some cool stuff before the target method is called return RemotingServices.ExecuteMessage(_instance, msg as IMethodCallMessage); } } Best Regards, -- Chris Taylor http://taylorza.blogspot.com http://twitter.com/taylorza "Richard" <richard (AT) newsgroups (DOT) nospam> wrote in message news:B974C716-9C9C-41D0-8BB5-3DC5FB4AB76E (AT) microsoft (DOT) com... Hello, I am trying to figure out how I can intercept calls made onto objects using the RealProxy mechanism. Works fine on the server side; but am unable to figure out how to do it on the client side. That is, if I understand correctly, I need to overload CreateProxy from the RealProxy class, which would allow me to create a proxy of my own... easy enough --- BUT how to I get to know which object this refers to once in a call with the invoke method? Any help would be greatly appreciated! |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |