public interface ICalculator
{
double Add(double x, double y);
double Multiply(double x, double y);
}
[AttributeUsage(AttributeTargets.Class)]
class PriorityProxyAttribute : ProxyAttribute
{
public override MarshalByRefObject CreateInstance(Type serverType)
{
MarshalByRefObject target = base.CreateInstance(serverType);
RealProxy pp = new PriorityProxy(target, serverType);
return (MarshalByRefObject)pp.GetTransparentProxy();
}
}
[PriorityProxy]
public class MyCalc : ContextBoundObject, ICalculator
{
public double Add(double x, double y) { return x + y; }
public double Multiply(double x, double y) { return x * y; }
}
class PriorityProxy : RealProxy
{
readonly MarshalByRefObject target;
public PriorityProxy(MarshalByRefObject target, Type type)
: base(type)
{
this.target = target;
}
public override IMessage Invoke(IMessage msg)
{
IMessage response = null;
IMethodCallMessage call = (IMethodCallMessage)msg;
IConstructionCallMessage ctor = call as IConstructionCallMessage;
// To do some interception job…
Console.WriteLine(call.MethodName);
if (ctor != null)
{
RealProxy defaultProxy = RemotingServices.GetRealProxy(target);
defaultProxy.InitializeServerObject(ctor);
MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();
response = EnterpriseServicesHelper.CreateConstructionReturnMessage(ctor, tp);
}
else
{
response = RemotingServices.ExecuteMessage(target, call);
}
return response;
}
}
class Program
{
static void Main(string[] args)
{
ICalculator calc = new MyCalc();
double val1 = calc.Add(1, 2);
double val2 = calc.Multiply(2, 3);
Console.WriteLine("value1: {0}, value2: {1}", val1, val2);
}
}
This is an advanced method call mechinanism in .NET CLR (I believe in that it is the underlayer of .NET Remoting), which we call a method as if we were sending a message. Here, it is a real message!
As we all know, when we calling a method, a physical stack frame will be created, where arguments and return address will be push onto stack. This is very useful when a method is called inter domain/process. But, what if we want to call a remote object’s method, this is across domain/process? How can we do? Yes, just as something Web Services do, we can convert stack frame to a message (serialing it so as to transfer on network if necessary), and on the remote domain/process convert it back to stack frame. I believe in that it is what .NET Remoting does.
The key points of above demo code is,
l TransparentProxy: convert stack frame to message.
l ExecuteMessage: stack builder sink, convert message back to stack frame.
Furthermore, it is also an interception technique, that we can use to see what method of an object is called during the runtime. In the demo code above, Add and Multiply will be intercepted.