HighTechTalks DotNet Forums  

ProxyAttribute, RealProxy.CreateProxy()

Dotnet Framework (Remoting) microsoft.public.dotnet.framework.remoting


Discuss ProxyAttribute, RealProxy.CreateProxy() in the Dotnet Framework (Remoting) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #11  
Old   
Richard
 
Posts: n/a

Default Re: ProxyAttribute, RealProxy.CreateProxy() - 10-05-2009 , 08:04 AM






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:

Quote:
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!

Reply With Quote
  #12  
Old   
Richard
 
Posts: n/a

Default Re: ProxyAttribute, RealProxy.CreateProxy() - 10-07-2009 , 03:04 PM






Hello? Chris?

"Richard" wrote:

Quote:
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?

--

Reply With Quote
  #13  
Old   
Richard
 
Posts: n/a

Default Re: ProxyAttribute, RealProxy.CreateProxy() - 10-13-2009 , 01:23 PM



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:

Quote:
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!

Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.